We’ve been using StructureMap for Dependency Injection in our ASP.Net MvC 3 web apps with C#, but today I’m unable to inject a needed type into a C# CustomResolver I’ve built.
Here is the code in our StructureMapInitialization.cs file:
namespace UI.DependencyResolution
{
/// <summary>
/// Class Structure Map IOC intialization
/// </summary>
public static class StructureMapIocInitialization
{
/// <summary>
/// Initialize Method for Structure Map IOC Initialization
/// </summary>
/// <returns>an IContainer for Services and Repository</returns>
public static IContainer Initialize()
{
ObjectFactory.Initialize(cfg =>
{
cfg.Scan(scan =>
{
scan.Assembly("Infrastructure");
scan.Assembly("Core");
scan.WithDefaultConventions();
scan.ConnectImplementationsToTypesClosing(typeof(IAlertGenerator<>));
scan.ConnectImplementationsToTypesClosing(typeof(IValidationRule<>));
});
cfg.For<IFilterProvider>().Use<StructureMapFilterProvider>();
cfg.For<IControllerActivator>().Use<StructureMapControllerActivator>();
cfg.SetAllProperties(c =>
{
c.WithAnyTypeFromNamespaceContainingType<ICustomerRepository>();
c.WithAnyTypeFromNamespaceContainingType<IMachineRepository>();
c.WithAnyTypeFromNamespaceContainingType<ICurrentUserService>();
c.WithAnyTypeFromNamespaceContainingType<ICircuitRegistrationRepository>();
c.WithAnyTypeFromNamespaceContainingType<IWorkflowRequestInformationRepository>();
c.WithAnyTypeFromNamespaceContainingType<IEnumerable<IAlertGenerator<Customer>>>();
});
});
return ObjectFactory.Container;
}
}
}
And here is a snippet of the code from our AutoMapperProfile.cs file:
Mapper.CreateMap<AbstractOrganization, DashboardDetails>()
.ForMember(dashboard => dashboard.AlertsDictionary,
member => member.ResolveUsing<OrganizationAlertResolver>()
.ConstructedBy(() => new OrganizationAlertResolver(
ObjectFactory.GetInstance<ICustomerRepository>(), ObjectFactory.GetInstance<IEnumerable<IAlertGenerator<Customer>>>())));
And here is my CustomResolver code:
namespace UI.Models.CustomResolvers
{
public class OrganizationAlertResolver : ValueResolver<Organization, Dictionary<string, string>>
{
private readonly ICustomerRepository _customerRepository;
/// <summary>
/// Storage for customer alert generator.
/// </summary>
private readonly IEnumerable<IAlertGenerator<Customer>> _customerAlertGenerators;
public OrganizationAlertResolver(ICustomerRepository customerRepository,
IEnumerable<IAlertGenerator<Customer>> customerAlertGenerators)
{
_customerRepository = customerRepository;
_customerAlertGenerators = customerAlertGenerators;
}
protected override Dictionary<string,string> ResolveCore(Organization organization)
{
var customers = _customerRepository.GetActiveCustomersByOrgNumber(organization.OrgNumber);
foreach (var generator in _customerAlertGenerators)
{
generator.PopulateAlerts(customers);
}
Dictionary<string, string> alertsDictionary = new Dictionary<string, string>();
foreach (var customer in customers)
{
foreach (var alert in customer.Alerts)
{
if(alertsDictionary.ContainsKey(alert.ToString()))
{
alertsDictionary[alert.ToString()] = alert.Message;
}
else
{
alertsDictionary.Add(alert.ToString(), alert.Message);
}
}
}
return alertsDictionary;
}
}
}
So, I’m trying to use StructureMap to inject the IEnumerable of IAlertGenerator of type Customer into my CustomResolver, but I get a StructureMap 202 Exception saying that there was no default instance of that type found, even though I created the instance of it in the last entry in the StructureMap initialization file.
Here is a copy of the error message I’m getting when I run it:
StructureMap Exception Code: 202 No Default Instance defined for
PluginFamily
System.Collections.Generic.IEnumerable1[[Core.Domain.Alerts.IAlertGenerator1[[Core.Domain.Model.Customer,
Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Core,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Can anyone help with suggestions on how to fix this problem?
In addition to what Mike has pointed out this issue can be caused by multiple instances closing the type. Based on your code:
I’m guessing that is what is happening.
It should be as simple as changing the above to:
which will find all instances which close
IAlertGenerator<Customer>.