Подтвердить что ты не робот

Unity - ввод различных классов для одного и того же интерфейса

У меня есть один интерфейс: IFoo
Два класса, реализующие этот интерфейс: FooOne и FooTwo
И два класса ClassOne и ClassTwo получают параметр IFoo в конструкторе.

Как я настраиваю единицу, поэтому ClassOne получает экземпляр FooOne, а ClassTwo получает FooTwo, используя только один контейнер?

Я не могу сделать это во время выполнения, поэтому он должен находиться в файле конфигурации.

4b9b3361

Ответ 1

Посмотрите Документация Unity.

Для более читаемого конфигурационного файла вы должны определить псевдонимы типов для IFoo, FooOne, FooTwo, ClassOne и ClassTwo. Затем вам нужно зарегистрировать сопоставления от IFoo к вашим реализациям. Вам нужно установить name для сопоставлений. Для потребителей IFoo вам необходимо зарегистрировать InjectionConstructor.

Ваша конфигурация будет выглядеть примерно так:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
      Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="IFoo" type="UnityConfigFile.IFoo, UnityConfigFile" />
    <alias alias="FooOne" type="UnityConfigFile.FooOne, UnityConfigFile" />
    <alias alias="FooTwo" type="UnityConfigFile.FooTwo, UnityConfigFile" />
    <alias alias="ClassOne" type="UnityConfigFile.ClassOne, UnityConfigFile" />
    <alias alias="ClassTwo" type="UnityConfigFile.ClassTwo, UnityConfigFile" />
    <container>
      <register type="IFoo" name="1" mapTo="FooOne" />
      <register type="IFoo" name="2" mapTo="FooTwo" />
      <register type="ClassOne" mapTo="ClassOne">
        <constructor>
          <param name="foo">
            <dependency type="IFoo" name="1" />
          </param>
        </constructor>
      </register>
      <register type="ClassTwo" mapTo="ClassTwo">
        <constructor>
          <param name="foo">
            <dependency type="IFoo" name="2" />
          </param>
        </constructor>
      </register>
    </container>
  </unity>
</configuration>

Это соответствующий тест, который показывает, как он работает.

UnityConfigurationSection config =
  (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
IUnityContainer container = new UnityContainer();
container.LoadConfiguration(config);
ClassTwo two = container.Resolve<ClassTwo>();
Assert.IsInstanceOfType(two.Foo, typeof(FooTwo));

Обновление

Во время выполнения вы можете сделать это следующим образом

IUnityContainer container = new UnityContainer();
container.RegisterType<IFoo, FooOne>("One");
container.RegisterType<IFoo, FooTwo>("Two");
container.RegisterType<ClassOne>(new InjectionConstructor(
  new ResolvedParameter<IFoo>("One")));
container.RegisterType<ClassTwo>(new InjectionConstructor(
  new ResolvedParameter<IFoo>("Two")));

Ответ 2

Вам нужно дать им регистрационные имена, чтобы сделать это:

// Create an instance of a service you want to use. Alternatively, this
// may have been created by another process and passed to your application
LoggingService myLoggingService = new LoggingService();

// Register the existing object instance with the container
container.RegisterInstance<IMyService>("Logging", myLoggingService);

// Register a mapping for another service your application will use
container.RegisterType<IMyService, myDataService>("DataService");

// When required, retrieve an instance of these services
IMyService theDataService = container.Resolve<IMyService>("DataService");
IMyService theLoggingService = container.Resolve<IMyService>("Logging");

Взято из Разрешение экземпляров типов с использованием единства

Ответ 3

Я устанавливаю в своем приложении, как это

Установленный пакет Unuget Unity версии 4.0.1

<package id="Unity" version="4.0.1" targetFramework="net452" />

В моем приложении App.config

<configSections>
     <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>

<unity>
    <container>
        <register type="MyApp.MainWindow, MyApp">
            <lifetime type="singleton" />
        </register>
        <register name="UnityResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.UnityResolver, Avelyn.Core" />
        <register name="NinjectResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.NinjectResolver, Avelyn.Core" />
    </container>
</unity>

В My App.xaml.cs

var _container = new UnityContainer();
_container.LoadConfiguration();

IResolver _unityResolver = _container.Resolve<IResolver>("UnityResolver");
IResolver _ninject  = _container.Resolve<IResolver>("NinjectResolver");
MainWindow _win = _container.Resolve<MainWindow>();