44

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

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

4

3 回答 3

47

Unity 无法做到这一点。你能做的最好的事情是:

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

或者您可以使用SmartConstructorTecX项目提供的。这篇博文描述了一些背景。

注册将如下所示:

container.RegisterType<Bar>(new SmartConstructor("text", "123"));
于 2012-08-08T19:17:40.293 回答
0

I used to do that as described in the answer above (that's using InjectionConstructor). The problem with that is that if the signature of the constructor is changed but InjectionConstructor is not updated, then we will know that only at run time. I think that there is a cleaner way to do that and without getting deep into details of the signature of the constructor. Here is how:

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() {}
}

Then when registering interfaces, just add:

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

That's all. if tomorrow Bar needs to take more or less parameters, then after adding or removing extra Foo<N + 1> Unity will still automatically construct Bar.

PS I don't think that interface IMyStringPrameterForBar is actually required. However, I prefer to see only interfaces in Unity registrations because it is much easier to twist them around during tests and/or for any other purpose.

于 2019-09-20T10:53:57.317 回答
0
public void Register<TFrom>(params object[] constructorParams) where TFrom : class
        {
            _container.RegisterType<TFrom>(new InjectionConstructor(constructorParams));
        }
于 2016-05-10T00:15:06.163 回答