【问题标题】:Unity and Object Creation统一和对象创建
【发布时间】:2011-02-25 08:23:23
【问题描述】:

我使用 unity 作为我的 IoC 容器。我正在尝试实现一种 IProviderRepository。具体实现有一个接受 IRepository 类型的构造函数。当我从具体实现中删除构造函数参数时,一切正常。我确定容器接线正确。当我尝试使用构造函数创建具体对象时,我收到以下错误:

"当前的构建操作(build key Build Key[EMRGen.Infrastructure.Data.IRepository1[EMRGen.Model.Provider.Provider], null]) failed: The current type, EMRGen.Infrastructure.Data.IRepository1[EMRGen.Model.Provider.Provider],是接口,无法构建。是不是缺少类型映射? (策略类型 BuildPlanStrategy,索引 3)”。

是否可以使用 Unity 实现上述功能?即让 Unity 从接口中推断出具体类型,并根据构造函数参数将具体类型的构造函数注入适当的具体对象。下面是我在 Unity 中定义的类型示例和我想要实现的骨架类列表。 IProviderRepository 由 ProviderRepository 实现,它有一个期望 IRepository 类型的构造函数。

 <typeAlias alias="ProviderRepositoryInterface" type="EMRGen.Model.Provider.IProviderRepository, EMRGen.Model" />
 <typeAlias alias="ProviderRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.Providers.ProviderRepository, EMRGen.Infrastructure.Repositories" />
 <typeAlias alias="ProviderGenericRepositoryInterface" type="EMRGen.Infrastructure.Data.IRepository`1[[EMRGen.Model.Provider.IProvider, EMRGen.Model]], EMRGen.Infrastructure" />
 <typeAlias alias="ProviderGenericRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.EntityFramework.ApplicationRepository`1[[EMRGen.Model.Provider.Provider, EMRGen.Model]], EMRGen.Infrastructure.Repositories" />
 <!-- Provider Mapping-->
 <typeAlias alias="ProviderInterface" type="EMRGen.Model.Provider.IProvider, EMRGen.Model" />
 <typeAlias alias="ProviderConcrete" type="EMRGen.Model.Provider.Doctor, EMRGen.Model" />

说明在我的课堂上进行的调用:

public class PrescriptionService
{
     PrescriptionService()
     {
         IUnityContainer uc = UnitySingleton.Instance.Container;
         UnityServiceLocator unityServiceLocator = new UnityServiceLocator(uc);
         ServiceLocator.SetLocatorProvider(() => unityServiceLocator);
         IProviderRepository pRepository =
             ServiceLocator.Current.GetInstance<IProviderRepository>();
     }
}

public class GenericRepository<IProvider> : IRepository<IProvider>
{
}

public class ProviderRepository :  IProviderRepository
{
    private IRepository<IProvider> _genericProviderRepository;

    //Explict public default constructor
    public ProviderRepository(IRepository<IProvider> genericProviderRepository) 
    {
        _genericProviderRepository = genericProviderRepository;
    }
}

【问题讨论】:

    标签: dependency-injection inversion-of-control unity-container


    【解决方案1】:

    您想做的事情是可能的,但您需要告诉 Unity 如何映射从接口到具体类型。 AFAICT,您当前的配置注册了很多类型,但没有指定它们之间的关系。

    也就是说,static Service Locator is an anti-pattern。考虑更改您的代码以改用正确的 构造函数注入。这也将大大简化您的代码:

    public class PrescriptionService
    {
        private readonly IProviderRepository pRepository;
    
        public PrescriptionService(IProviderRepository pRepository)
        {
            if (pRepository == null)
            {
                throw new ArgumentNullException("pRepository");
            }
    
            this.pRepository = pRepository;
        }
    }
    

    使用 Unity,您可以像这样连接它:

    var container = new UnityContainer();
    container.RegisterType<PrescriptionService>();
    container.RegisterType<IProviderRepository, ProviderRepository>();
    container.RegisterType<IRepository<IProvider>, MyRepository<IProvider>>();
    
    var ps = container.Resolve<PrescriptionService>();
    

    配置容器和resolve all components in the application's Composition Root

    你应该only use XML configuration if you need to be able to change certain components without recompiling your application

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-11
      • 2013-12-04
      • 2021-01-13
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      相关资源
      最近更新 更多