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

时间:2009-03-06 08:15:48

标签: c# .net unity-container

我在Unity中尝试以下内容:

我有一个带有以下构造函数的类型

public Type1(Type2 firstDependency, Type3 secondDependency)

使用Unity解析Type1时,我想指定要注入的Type2的特定实例。 Type2的此特定实例未在容器中注册。 Type3已在容器中注册,应照常解决。

更具体地说,请考虑Type1DocumentViewer类。 Type2是具体的DocumentType3SpellingChecker

我希望能够解析DocumentViewer只能在运行时知道的Document。可以创建多个DocumentViewer个不同Documents的实例。

我该怎么做?

6 个答案:

答案 0 :(得分:2)

这是我做的一个简单示例,您使用RegisterInstance或者您可以使用Lifetime管理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;
    }
}

更新:我在构造函数中包含了一个带有两个参数的类型,以表明它也可以解析。

答案 1 :(得分:0)

我不想在原始容器中注册Type2的实例。对于Type1的不同实例,type2的实例可以是不同的。

我的下一步尝试是创建一个子容器,并在那里注册Type2的特定实例。

答案 2 :(得分:0)

尝试使用命名实例:


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()”参数将初始化抵制类型的单例实例,因此您将始终获得类型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();

答案 3 :(得分:0)

如果您有一个具有多个构造函数的类,则可以使用“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)
    {
    }
}

答案 4 :(得分:0)

使用工厂。

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仅解析一个参数构造函数。

答案 5 :(得分:0)

您可以使用容器层次结构,请在此处阅读我对类似问题的回答:Microsoft Unity. How to specify a certain parameter in constructor?

唯一的区别是看起来应该在您的子容器中使用RegisterInstance()而不是RegisterType()。也许不是,这取决于您是否在代码之外的某个地方创建了实例。