Unity 为一个接口注册多个对象,并告诉 Unity 在哪里注入它们

本文关键字:Unity 在哪里 注入 一个 注册 接口 对象 | 更新日期: 2023-09-27 18:30:31

嗨,我一直在尝试告诉 Unity 对于接口,如果它有多个实现,我希望它将它们注入到不同的类中。我的意思是:

假设我有一个接口IProductCatalogService和两个实现 ProductCatalog : IProductCatalogServiceProductCatalogService : IProductCatalogService .

我将如何告诉 Unity 对于类 A,我希望在我的构造函数中传递一个类型 ProductCatalog 的实例,对于类 B,我想要一个 ProductCatalogService 的实例。

我正在 ASP.NET Web API 项目中使用 Unity,并且我已经在 GLobalConfiguration 中设置了解析程序。

对于简单的 1 对 1 注册,一切正常。

这是我尝试过的,但它似乎不起作用:

public class DependencyServiceModel
{
    public Type From { get; set; }
    public Type To { get; set; }
    public IEnumerable<Type> ForClasses { get; set; }
}
public void RegisterTypeForSpecificClasses(DependencyServiceModel dependencyService)
{
    foreach (var forClass in dependencyService.ForClasses)
    {
        string uniquename = Guid.NewGuid().ToString();
        Container.RegisterType(dependencyService.From, 
            dependencyService.To, uniquename);
        Container.RegisterType(forClass, uniquename, 
            new InjectionConstructor(
                new ResolvedParameter(dependencyService.To)));
    }
}

DependencyServiceModel中,From是接口,To是我要实例化的对象,ForClasses是我想使用To对象的类型。

Unity 为一个接口注册多个对象,并告诉 Unity 在哪里注入它们

在下面的示例中,您有一个接口实现了两次,并根据需要注入到两个不同的客户端类中,就像您请求的那样。诀窍是使用命名注册。

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();
        container.RegisterType<IFoo, Foo1>("Foo1");
        container.RegisterType<IFoo, Foo2>("Foo2");
        container.RegisterType<Client1>(
            new InjectionConstructor(new ResolvedParameter<IFoo>("Foo1")));
        container.RegisterType<Client2>(
            new InjectionConstructor(new ResolvedParameter<IFoo>("Foo2")));
        Client1 client1 = container.Resolve<Client1>();
        Client2 client2 = container.Resolve<Client2>();
    }
}
public interface IFoo {  }
public class Foo1 : IFoo {  }
public class Foo2 : IFoo { }
public class Client1
{
    public Client1(IFoo foo) { }
}
public class Client2
{
    public Client2(IFoo foo) { }
}

这很可能是你做错了什么:

Container.RegisterType(forClass, uniquename, 
    new InjectionConstructor(
        new ResolvedParameter(dependencyService.To)));

为具体类创建命名注册。相反,你应该有

Container.RegisterType(forClass, null, 
    new InjectionConstructor(
        new ResolvedParameter(dependencyService.To, uniquename)));

很高兴知道。如果您将多种类型注册到一个接口,例如 belove;

container.RegisterType<ITransactionsService, EarningsManager>();
container.RegisterType<ITransactionsService, SpendingsManager>();

您无法通过以下方式获取类型列表;

IEnumerable<ITransactionsService> _transactionsService;

列表中将始终是最后注册的类型(支出管理器)。

为了防止这种情况;

container.RegisterType<ITransactionsService, EarningsManager>("EarningsManager");
container.RegisterType<ITransactionsService, SpendingsManager>("SpendingsManager");

您必须以这种方式更改代码。