繁体   English   中英

Unity:如何在解析另一种类型时指定使用类型的特定实例

[英]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在容器中注册,应该像往常一样解析。

更具体地说,考虑Type1DocumentViewer 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM