2

我们一直在使用 C# 在我们的 ASP.Net MvC 3 Web 应用程序中使用 StructureMap 进行依赖注入,但是今天我无法将所需的类型注入到我构建的 C# CustomResolver 中。

这是我们的 StructureMapInitialization.cs 文件中的代码:

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;
    }
}

}

这是我们 AutoMapperProfile.cs 文件中的代码片段:

Mapper.CreateMap<AbstractOrganization, DashboardDetails>()
    .ForMember(dashboard => dashboard.AlertsDictionary,
    member => member.ResolveUsing<OrganizationAlertResolver>()
    .ConstructedBy(() => new OrganizationAlertResolver(
        ObjectFactory.GetInstance<ICustomerRepository>(), ObjectFactory.GetInstance<IEnumerable<IAlertGenerator<Customer>>>())));

这是我的 CustomResolver 代码:

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;
        }
    }
}

因此,我正在尝试使用 StructureMap 将 Customer 类型的 IAlertGenerator 的 IEnumerable 注入到我的 CustomResolver 中,但是我得到一个 StructureMap 202 异常,说没有找到该类型的默认实例,即使我在其中创建了它的实例StructureMap 初始化文件中的最后一个条目。

这是我运行它时收到的错误消息的副本:

StructureMap 异常代码:202 没有为 PluginFamily System.Collections.Generic.IEnumerable 定义默认实例1[[Core.Domain.Alerts.IAlertGenerator1[[Core.Domain.Model.Customer,Core,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null]],Core,Version =1.0.0.0,文化=中性,PublicKeyToken=null]],mscorlib,版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089

任何人都可以提供有关如何解决此问题的建议吗?

4

2 回答 2

2

除了Mike 指出的,这个问题可能是由多个实例关闭类型引起的。根据您的代码:

ObjectFactory.GetInstance<IEnumerable<IAlertGenerator<Customer>>>()

我猜这就是正在发生的事情。

它应该像将上面的内容更改为一样简单:

ObjectFactory.GetAllInstances<IAlertGenerator<Customer>>()

这将找到所有关闭的实例IAlertGenerator<Customer>

于 2012-09-25T17:01:11.873 回答
0

我不是 100% 确定这里发生了什么,但是当我收到此错误时,我在 StructureMap 中看到了两个不同的问题。第一个是被实例化的类需要一个无参数的构造函数,所以Customer可能没有。

第二个是即使存在无参数构造函数,StructureMap 也会尝试使用最完全限定的构造函数,我已经在SqlConnection. 以下是如何解决此问题的示例。

x.ForRequestedType<IDbConnection>()
    .CacheBy(InstanceScope.Singleton)
    .TheDefault.Is.ConstructedBy(ctor => new SqlConnection("connection string"));

请注意,我必须使用.TheDefault.Is.ConstructedBy构造来让它使用正确的构造函数。在诉诸于此之前,我曾尝试使用.Ctor构造传递参数,但无法使其正常工作。

我希望这有助于为您指明正确的方向。

于 2012-09-25T12:34:33.840 回答