Unity:告诉容器在注册类型时始终使用接口的特定实现

问题描述 投票:0回答:2

我一直遇到这种情况:假设我有接口IFoo和几种实现,例如RedFoo : IFooBlackFoo : IFoo。然后,我有了在构造函数中使用IFoo的类:

class BlackFooUser
{
   public BlackFooUser(IFoo foo, other_parameters_here) {...}
}

class RedFooUser
{
   public RedFooUser(IFoo foo, other_parameters_here) {...}
}

我如何告诉容器照常解析所有其他参数,但是在构造BlackFoo时始终使用BlackFooUser,而在构造RedFoo时始终使用RedFooUser?我知道我可以在调用ParameterOverride时使用Resolve(),但是我希望在解析Red/BlackFooUser时它都一样,因此应该将其放入RegisterTypeRegisterFactory

我可以做类似的事情

container.RegisterFactory<RedFooUser>(c=>new RedFooUser(c.Resolve<RedFoo>(), other_parameters_here));

但这很冗长,每次添加新参数时,都必须更改。

还有更好的方法吗?

c# inversion-of-control unity-container
2个回答
0
投票

使用抽象类和泛型来强制使用特定类型。

Unity将自动解析具体类型,因此您无需注册它们。

public abstract class FooUser<TFoo> where TFoo : IFoo
{
    private readonly TFoo _foo;
    public FooUser(TFoo foo, other parameters)
    {
        _foo = foo;
    }
}

public class BlackFooUser : FooUser<BlackFoo>
{
    public BlackFooUser (BlackFoo foo, other parameters)
        : base(foo, other parameters)
    {
    }
}

public class RedFooUser : FooUser<RedFoo>
{
    public RedFooUser (RedFoo foo, other parameters)
        : base(foo, other parameters)
    {
    }
}

下面的完整复制-输出为:

使用foo'RedFoo'和otherParameter'我是另一个参数'构造RedFooUser'使用foo'BlackFoo'和otherParameter'我是另一个参数'构造了BlackFooUser

void Main()
{
    var container = new UnityContainer()
        .RegisterInstance<string>("I'm the other parameter");

    var foo1 = container.Resolve<RedFooUser>();
    var foo2 = container.Resolve<BlackFooUser>();

}

// Define other methods, classes and n
public interface IFoo 
{
}
public class BlackFoo : IFoo { }
public class RedFoo : IFoo { }

public abstract class FooUser<TFoo> where TFoo : IFoo
{

    private readonly TFoo _foo;
    public FooUser(TFoo foo, string otherParameter)
    {
        _foo = foo;
        Console.WriteLine($"Constructed {GetType().Name} with foo '{foo.GetType().Name}' and otherParameter '{otherParameter}'");
    }
}

public class BlackFooUser : FooUser<BlackFoo>
{
    public BlackFooUser(BlackFoo foo, string otherParameter)
        : base(foo, otherParameter)
    {
    }
}

public class RedFooUser : FooUser<RedFoo>
{
    public RedFooUser(RedFoo foo, string otherParameter)
        : base(foo, otherParameter)
    {
    }
}

0
投票

注册类型时,可以给它们命名,然后在注入这些类型的构造函数中引用该名称。像这样的东西:

© www.soinside.com 2019 - 2024. All rights reserved.