Autofac проводка вопрос - новичок - PullRequest
0 голосов
/ 05 марта 2011

Вопрос для начинающих: Учитывая два класса: Myclass5 и Myclass6, как можно подключиться, следуя фабричному методу (возвращается как Func) такой, что Все экземпляры myclass5 и myclass6, а также IMyClass, от которых они зависят, извлекаются через автофак (при условии, что эти три экземпляра зарегистрированы).

   public static MyClass4 FactoryMethod(int nu)
    {
        if (nu == 1)
            return new MyClass5(....);
        if (nu == 4)
            return new MyClass6(....);

        throw new NotImplementedException();
    }

public abstract class MyClass4
{

}

public class MyClass5 : MyClass4
{
    public MyClass5(int nu, IMyClass a)
    {

    }
}

public class MyClass6 : MyClass4
{
    public MyClass6(int nu, IMyClass a)
    {

    }
}

1 Ответ

3 голосов
/ 06 марта 2011

Чтобы 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));
...