2012-09-19 72 views
1

我們一直在用C#在ASP.Net MvC 3網絡應用程序中使用StructureMap進行依賴注入,但是今天我無法將所需的類型注入到我構建的C#CustomResolver中。結構圖的C#依賴注入

這裏是我們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 Exception,它說沒有找到該類型的默認實例,即使我創建了它位於StructureMap初始化文件的最後一個條目中。

這是我收到錯誤消息的副本,當我運行它:

StructureMap異常代碼:202無默認實例 PluginFamily System.Collections.Generic.IEnumerable 1[[Core.Domain.Alerts.IAlertGenerator 1定義[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

任何人都可以提供有關如何解決此問題的建議嗎?

回答

2

除了什麼Mike has pointed out這個問題可能是由多個關閉類型的實例引起的。根據你的代碼:

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

我猜這就是發生了什麼。

它應該是爲改變上述以簡單:

ObjectFactory.GetAllInstances<IAlertGenerator<Customer>>() 

將發現其關閉IAlertGenerator<Customer>所有實例。

0

我並不是100%確定這裏發生了什麼,但是在得到這個錯誤時,我在StructureMap中看到了兩個不同的問題。第一個是被實例化的類需要一個無參數的構造函數,因此Customer可能沒有。

其次,即使存在無參數構造函數,StructureMap也會嘗試使用最完全合格的構造函數,並且我已經看到類如SqlConnection。以下是如何解決該問題的示例。

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

注意,我不得不使用.TheDefault.Is.ConstructedBy結構得到它使用正確的構造函數。在採取這一措施之前,我試圖通過使用.Ctor結構來傳遞參數,但無法使其正常工作。

我希望這可以幫助您指出正確的方向。