Чтобы FactoryMethod
мог создавать экземпляры, требуется доступ к контейнеру. Я бы предложил создать тип делегата для фабричного метода, который позволяет легко получить зависимость от него. Регистрация идет так:
var cb = new ContainerBuilder();
cb.RegisterType<SomeClass>().As<IMyClass>();
cb.RegisterType<MyClass5>();
cb.RegisterType<MyClass6>();
cb.Register((c, p) =>
{
var context = c.Resolve<IComponentContext>();
return new FactoryMethod(nu =>
{
var nuParameter = TypedParameter.From(nu);
switch (nu)
{
case 1:
return context.Resolve<MyClass5>(nuParameter);
case 4:
return context.Resolve<MyClass6>(nuParameter);
default:
throw new NotImplementedException();
}
});
});
var container = cb.Build();
Во время разрешения вы можете взять зависимость от типа делегата FactoryMethod
и использовать ее для разрешения экземпляров:
var factory = container.Resolve<FactoryMethod>();
var instance5 = factory(1);
var instance6 = factory(1);
Примечание: создаваемый нами экземпляр делегата нуждается в контексте. Мы не можем использовать параметр c
напрямую, поскольку этот контекст является только временным. Таким образом, мы должны разрешить IComponentContext
, чтобы «запечь» лямбду.
Обновление: если вы хотите извлечь фабричную реализацию в метод, который не зависит от контейнера, я бы предложил следующее:
public class FactoryMethodImpl
{
readonly Func<int, MyClass5> _factory5;
readonly Func<int, MyClass6> _factory6;
public FactoryMethodImpl(Func<int, MyClass5> factory5, Func<int, MyClass6> factory6)
{
_factory5 = factory5;
_factory6 = factory6;
}
public MyClass4 Create(int nu)
{
switch (nu)
{
case 1:
return _factory5(nu);
case 4:
return _factory6(nu);
default:
throw new NotImplementedException();
}
}
}
Теперь измените регистрационный код на:
var cb = new ContainerBuilder();
cb.RegisterType<SomeClass>().As<IMyClass>();
cb.RegisterType<MyClass5>();
cb.RegisterType<MyClass6>();
cb.RegisterType<FactoryMethodImpl>().SingleInstance();
cb.Register(c=> new FactoryMethod(c.Resolve<FactoryMethodImpl>().Create));