团结与对象创造

时间:2010-05-28 22:27:58

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

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

  

“当前构建操作(构建密钥构建密钥[EMRGen.Infrastructure.Data.IRepository 1[EMRGen.Model.Provider.Provider], null]) failed: The current type, EMRGen.Infrastructure.Data.IRepository 1 [EMRGen.Model.Provider.Provider],是一个接口,无法构造。是否缺少类型映射?(策略类型BuildPlanStrategy,索引3)“。

是否可以通过Unity实现上述功能?也就是说,Unity从Interface推断出具体类型,并根据构造函数参数注入具体类型的构造函数和相应的具体对象。下面是我在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;
    }
}

1 个答案:

答案 0 :(得分:2)

您想要做的是什么,但您需要告诉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