6

我在 Unity 中尝试以下操作:

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

public Type1(Type2 firstDependency, Type3 secondDependency)

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

更具体地说,考虑Type1是一个DocumentViewer类。Type2是一个特定的Document. Type3是一个SpellingChecker

我希望能够解决仅DocumentViewerDocument运行时才知道的问题。可以创建不同的多个DocumentViewer实例。Documents

我怎样才能做到这一点?

4

5 回答 5

2

这是我制作的一个简单示例,您使用 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;
    }
}

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

于 2009-03-06T08:21:22.590 回答
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();

于 2009-03-06T08:35:10.467 回答
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 仅解析一个参数构造函数。

于 2009-04-21T03:26:07.937 回答
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)
    {
    }
}

于 2009-03-06T10:40:35.500 回答
0

您可以使用容器层次结构,请在此处阅读我对类似问题的回答:Microsoft Unity。如何在构造函数中指定某个参数?.

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

于 2011-04-21T09:15:03.750 回答