用于多参数构造函数的Unity InjectionConstructor仅覆盖单个构造函数

时间:2012-08-08 14:24:17

标签: c# unity-container

我有一个像这样的构造函数的类:

public class Bar
{
    public Bar(IFoo foo, IFoo2 foo2, IFoo3 foo3, IFooN fooN, String text)
    {

    }
}

我想在Unity中注册Bar并为文本提供值:

unity.RegisterType<Bar, Bar>(new InjectionConstructor("123"));

但是我无法做到这一点,因为Bar没有单一的参数构造函数。

有没有办法为文本提供值而不指定所有其他参数ResolvedParameter<IFooN>等。我真的不喜欢它,很多代码,每次我更改Bar的构造函数我需要添加另一个ResolvedParameter

3 个答案:

答案 0 :(得分:42)

Unity无法开箱即用。你能做的最好的是:

container.RegisterType<Bar>(
    new InjectionConstructor(
        typeof(IFoo), typeof(IFoo2), typeof(IFoo3), typeof(IFooN), "123"));

或者您可以使用TecX项目提供的SmartConstructorThis blog post描述了一些背景知识。

注册将如下所示:

container.RegisterType<Bar>(new SmartConstructor("text", "123"));

答案 1 :(得分:0)

public void Register<TFrom>(params object[] constructorParams) where TFrom : class
        {
            _container.RegisterType<TFrom>(new InjectionConstructor(constructorParams));
        }

答案 2 :(得分:0)

我曾经按照上面的答案(使用InjectionConstructor)进行操作。这样做的问题是,如果更改了构造函数的签名,但是InjectionConstructor没有更新,那么我们只会在运行时知道这一点。我认为有一种更干净的方法可以做到这一点,而不必深入了解构造函数签名的细节。方法如下:

public interface IBar
{
    void DoSomethingWithBar();
}

public interface IMyStringPrameterForBar
{
    string Value { get; }
}

public class MyStringPrameterForBar : IMyStringPrameterForBar
{
    public string Value { get; }
    public MyStringPrameterForBar(string value) => Value = value; 
}

public class Bar : IBar
{
    public Bar(IFoo foo, IFoo2 foo2, IFoo3 foo3, IFooN fooN, IMyStringPrameterForBar text)
    {
    }

    public void DoSomethingWithBar() {}
}

然后在注册接口时,只需添加:

unity.RegisterType<IFoo, Foo>();
unity.RegisterType<IFoo2, Foo2>();
unity.RegisterType<IFooN, FooN>();
unity.RegisterInstance(new MyStrignPrameterForBar("123"));
unity.RegisterType<IBar, Bar>();

仅此而已。如果明天Bar需要使用更多或更少的参数,那么在添加或删除多余的Foo<N + 1>之后,Unity仍将自动构造Bar

PS我认为实际上不需要接口IMyStringPrameterForBar。但是,我更喜欢仅在Unity注册中查看接口,因为在测试过程中和/或出于其他任何目的将它们扭曲起来要容易得多。