Unity - множественная регистрация интерфейса с фабричным методом для возврата одной и той же реализации - PullRequest
0 голосов
/ 20 декабря 2011

Представьте, что у меня есть следующие типы:

public interface IBaseInterface { }

public interface IInheritedInterface : IBaseInterface { }

public class MyClass : IInheritedInterface { }

//------------------------------------------------------------

public interface ISomeInterface { }

public class SomeClass : ISomeInterface {
  private readonly IBaseInterface _myInterface;

  public SomeClass(IBaseInterface myInterface) {
    _myInterface = myInterface;
  }
}

//------------------------------------------------------------

public interface ISomeOtherInterface { }

public class SomeOtherClass : ISomeOtherInterface {
  private readonly IInheritedInterface _myInterface;

  public SomeOtherClass(IInheritedInterface myInterface) {
    _myInterface = myInterface;
}

//------------------------------------------------------------

Итак, чего я пытаюсь достичь и задаюсь вопросом, как можно было бы сделать, если это возможно, то, что всякий раз, когда я строю либо SomeClass, либо SomeOtherClassвсегда получать один и тот же экземпляр MyClass.Этот пример объясняет, что я хочу:

var someClass = _container.Resolve<SomeClass>();
var someOtherClass = _container.Resolve<SomeOtherClass>();
// At this point, The following assert should pass
Assert.AreSame(someClass._myInterface, someOtherClass._myInterface)

Также обратите внимание, что MyClass необходимо зарегистрироваться, используя фабричный метод по другим причинам.Я пробовал следующее:

_container.RegisterType<IBaseInterface, MyClass>(
    perRequestLifetime, 
    new InjectionFactory((c) => 
        { return FactoryMethod(c); }));

Это разрешит SomeClass, но выбросит при попытке разрешить SomeOtherClass, так как контейнер не знает, как построить IInheritedInterface.

Я также попробовал это:

_container.RegisterType<IBaseInterface, MyClass(
    perRequestLifetime,
    new InjectionFactory((c) => {
        MyClass myClass;
        // Construct object some how...
        return myClass;
    }));

_container.RegisterType<IInheritedInterface, MyClass(
    perRequestLifetime,
    new InjectionFactory((c) => {
        return c.Resolve<IBaseInterface>() as MyClass;
    }));

Однако, по какой-то причине, когда я звоню Resolve() на оба SomeClass и SomeOtherClass, они оба заканчивают тем, что вызывают фабрику IInheritedInterface, вызывая бесконечноепетля!Затем я удалил регистрацию IBaseInterface и теперь разрешаю SomeClass бросков.

Есть идеи?

Спасибо

1 Ответ

3 голосов
/ 20 декабря 2011

Попробуйте это

container.RegisterType<IBaseInterface, MyClass>(new ContainerControlledLifetimeManager(), new InjectionFactory(ctr => new MyClass()));
container.RegisterType<IInheritedInterface, MyClass>();
...