![](/img/trans.png)
[英]How can I specify a constructor for Unity to use when resolving a service?
[英]Unity: how to specify to use specific instance of a type when resolving another type
我正在 Unity 中尝试以下操作:
我有一个带有以下构造函数的类型
public Type1(Type2 firstDependency, Type3 secondDependency)
使用 Unity 解析Type1
时,我想指定要注入的Type2
的特定实例。 Type2
的这个特定实例未在容器中注册。 Type3
在容器中注册,应该像往常一样解析。
更具体地说,考虑Type1
是DocumentViewer
class。 Type2
是一个特定的Document
。 Type3
是一个SpellingChecker
。
我希望能够为仅在运行时知道的Document
解析DocumentViewer
。 可以为不同的Documents
创建多个DocumentViewer
实例。
我怎样才能做到这一点?
这是我制作的一个简单示例,您使用 RegisterInstance 或者您可以使用 Lifetime management Claas
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<Type1>();
container.RegisterInstance<Type2>(new Type2());
Type1 t = container.Resolve<Type1>();
Type2 t2 = container.Resolve<Type2>();
Type3 t3 = container.Resolve<Type3>();
Console.ReadKey();
}
public class Type1
{
}
public class Type2
{
}
public class Type3
{
private Type1 t;
private Type2 t2;
public Type3(Type1 t, Type2 t2)
{
this.t = t;
this.t2 = t2;
}
}
更新:我在构造函数中包含了一个带有两个参数的类型,以表明它也可以被解析。
您可以使用容器层次结构,请在此处阅读我对类似问题的回答: Microsoft Unity。 如何在构造函数中指定某个参数? .
唯一的区别是您应该在子容器中使用RegisterInstance()
而不是RegisterType()
。 也许不是,这取决于您是否在代码之外的某个地方创建了实例。
我不想在原始容器中注册 Type2 的实例。 对于 Type1 的不同实例,type2 的实例可能不同。
我的下一个尝试是创建一个子容器,并在那里注册 Type2 的特定实例。
尝试使用命名实例:
IUnityContainer container = new UnityContainer();
container.RegisterType<Type1>();
container.RegisterType<Type2>("Instance 1", new ContainerControlledLifetimeManager());
container.RegisterType<Type2>("Instance 2", new ContainerControlledLifetimeManager());
container.RegisterType<Type3>();
Type1 type1 = container.Resolve<Type1>();
if (type1 == ...)
{
Type2 instance1 = container.Resolve<Type2>("Instance 1");
}
else
{
Type2 instance2 = ontainer.Resolve<Type2>("Instance 2");
}
您可以对类型 1 进行一些检查并决定您需要哪个类型 2 的实例。 请注意,“new ContainerControlledLifetimeManager()”参数将初始化一个抵抗类型的 singleton 实例,因此您将始终获得相同的类型 2 实例。
更新:与接口相同。 希望这可以帮助。
IUnityContainer container = new UnityContainer();
container.RegisterType<TextDocument>();
container.RegisterType<ImageDocument>();
container.RegisterType(typeof (IView), typeof (TextView), "Text", new ContainerControlledLifetimeManager());
container.RegisterType(typeof (IView), typeof (ImageView), "Image", new ContainerControlledLifetimeManager());
IDocument document = container.Resolve<TextDocument>();
IView view = null;
if (document is TextDocument)
{
view = container.Resolve<IView>("Text");
}
else
{
view = container.Resolve<IView>("Image");
}
view.Show();
如果您有一个带有多个构造函数的 class,您可以使用“InjectionConstructor”属性决定 Unity 容器使用哪个构造函数。 这使您可以手动设置一些参数。
public class Test
{
public Test()
{
}
// Always use the following constructor
[InjectionConstructor]
public Test(Type1 type1) : this()
{
}
public Test(Type1 type1, Type2 type2) : this(type1)
{
}
}
使用工厂。
public class Type1Factory
{
private Type3 type3;
public Type1Factory(Type3 _type3)
{
type3 = _type3;
}
public GetType1(Type2 type2)
{
return new Type1(type2, type3);
}
}
这样称呼它:
// SpellingChecker is subclass of Type3
IUnityContainer container = new UnityContainer();
container.RegisterType<Type3>(typeof(SpellingChecker));
// DocumentViewer is subclass of Type2
Type1Factory factory = container.Resolve<Type1Factory>();
Type1 type1 = factory.GetType1(new DocumentViewer());
这假设您只是尝试使用 Unity 来解决 Type3 依赖项,并且您无法控制 Type1 中的构造函数。 如果您可以编辑 Type1,请使用 Alexader R. 的建议使 Unity 仅解析一个参数构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.