Skip to main content
 首页 » 编程设计

c#之如何使用 Unity 解析接口(interface)集合

2024年02月05日26落叶无声

我有一个带有构造函数的类,它接受子接口(interface)的集合

public class Manager : IManager 
{ 
   public Manager(IEnumerable<IDataAccess> dataAccess) 
   { 

IDataAccess 是一个基础接口(interface)

public interface IFooDataAccess : IDataAccess 
{ 
 
public interface IBarDataAccess : IDataAccess 
{ 
 
public interface IBazDataAccess : IDataAccess 
{ 

其中每一个都有具体的实现。 当我解析 IManager 时,我希望使用 FooDataAccess、BarDataAccess 和 BazDataAccess 的集合填充 dataAccess 参数。

我正在使用 unity 作为 IoC,当前注册是:

    public static void RegisterTypes(IUnityContainer container) 
    { 
        container.RegisterTypes(AllClasses.FromAssemblies( 
                typeof(IManager).Assembly), 
            WithMappings.FromMatchingInterface, 
            WithName.Default, 
            WithLifetime.ContainerControlled); 

我在解决方案中也有一些其他类(因此使用注册模式)所以我想保留它。我一直在尝试自己注册 IManager:

        var allDataAccesses = container.ResolveAll<IDataAccess>(); 
        var parameter = new InjectionConstructor(allDataAccesses); 
        container.RegisterType<IManager, Manager>(parameter); 

但我无法让它工作,我错过了什么。如何配置 unity 来解析构造函数?

请您参考如下方法:

您所做的注册将映射直接实现的接口(interface)而不是 IDataAccess .

例如,它会映射IFooDataAccess至 FooDataAccess .你需要的是映射 IDataAccess至 FooDataAccess例如。

要解决这个问题,请添加以下注册码:

container.RegisterTypes( 
    typeof (IManager) 
        .Assembly 
        .GetTypes() 
        .Where(x => x.IsClass) 
        .Where(x => typeof (IDataAccess).IsAssignableFrom(x)), 
    x => new[] {typeof (IDataAccess)}, 
    WithName.TypeName, WithLifetime.ContainerControlled); 

这将在程序集中搜索实现 IDataAccess 的类(直接或间接),并将在 IDataAccess 之间创建一个映射和这些类(class)。

这里要注意的一件重要事情是它为注册提供了一个名称。这很重要,因为如果您有接口(interface) IDataAccess映射到许多类,则不能使用默认名称。 unity 如何知道要使用哪个映射条目?

您需要做的另一件事是映射 IEnumerable<IDataAccess>至 IDataAccess[]像这样:

container.RegisterType<IEnumerable<IDataAccess>, IDataAccess[]>(); 

Unity 知道如何通过查看所需接口(interface)的命名注册来解析数组。默认情况下,它不能对 IEnumerable<T> 执行相同的操作.另一种方法是更改​​构造函数以使用如下数组:

public class Manager : IManager 
{ 
    public Manager(IDataAccess[] dataAccess) 
    { 
        .... 
    } 
 
    .... 
}