C# 用于多参数构造函数的 Unity InjectionConstructor 仅覆盖单个构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11866643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unity InjectionConstructor for multiparam constructor overriding only single one
提问by Alex Burtsev
I have a class with constructor like this:
我有一个带有构造函数的类,如下所示:
public class Bar
{
public Bar(IFoo foo, IFoo2 foo2, IFoo3 foo3, IFooN fooN, String text)
{
}
}
I want to register Bar in Unity and provide a value for text:
我想在 Unity 中注册 Bar 并为文本提供一个值:
unity.RegisterType<Bar, Bar>(new InjectionConstructor("123"));
However I can't do this because there is no single parameter constructor for Bar.
但是我不能这样做,因为 Bar 没有单参数构造函数。
Is there a way to provide a value for text without specifying all other parameters as ResolvedParameter<IFooN>etc.. I really don't like it, lot's of code, and every time I change a constructor of Bar I need to add another ResolvedParameter
有没有办法在不指定所有其他参数的情况下为文本提供值ResolvedParameter<IFooN>等。我真的不喜欢它,很多代码,每次我更改 Bar 的构造函数时,我都需要添加另一个 ResolvedParameter
回答by Sebastian Weber
Unity can't do this out of the box. The best you can do is:
Unity 不能开箱即用。你能做的最好的是:
container.RegisterType<Bar>(
new InjectionConstructor(
typeof(IFoo), typeof(IFoo2), typeof(IFoo3), typeof(IFooN), "123"));
Or you can use the SmartConstructorprovided by the TecXproject. This blog postdescribes some background.
或者您可以使用TecX项目SmartConstructor提供的。这篇博文描述了一些背景。
Registration would look like this:
注册看起来像这样:
container.RegisterType<Bar>(new SmartConstructor("text", "123"));
回答by aecrch
public void Register<TFrom>(params object[] constructorParams) where TFrom : class
{
_container.RegisterType<TFrom>(new InjectionConstructor(constructorParams));
}
回答by Konstantin Konstantinov
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 InjectionConstructoris 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:
我曾经按照上面的答案(即使用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() {}
}
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 Barneeds to take more or less parameters, then after adding or removing extra Foo<N + 1>Unity will still automatically construct Bar.
就这样。如果明天Bar需要取更多或更少的参数,那么在添加或删除额外的Foo<N + 1>Unity 后仍然会自动构建Bar.
PS I don't think that interface IMyStringPrameterForBaris 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.
PS我认为IMyStringPrameterForBar实际上不需要该接口。然而,我更喜欢在 Unity 注册中只看到接口,因为在测试和/或任何其他目的期间更容易扭转它们。

