我有一个像这样的构造函数的类:
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
答案 0 :(得分:42)
Unity无法开箱即用。你能做的最好的是:
container.RegisterType<Bar>(
new InjectionConstructor(
typeof(IFoo), typeof(IFoo2), typeof(IFoo3), typeof(IFooN), "123"));
或者您可以使用TecX项目提供的SmartConstructor
。 This 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注册中查看接口,因为在测试过程中和/或出于其他任何目的将它们扭曲起来要容易得多。