2016-01-20 8 views
1

я с трудом интегрирующую autofac в моем applcation ..Autofac решительность в глубоком слое

Мое приложение интегрируется с другими приложениями, когда соединение с другим приложением, его поддерживается с помощью фитинга «Протокол» объекта

// This class is inherited by a few other classes 
public abstract class Protocol 

У меня есть слой, который запускается собственным потоком и обрабатывает запросы на соединение. Для каждого вида запроса создается другой вид протокола (другой объект протокола)

// For example lets say every protocol (Inhertiance of Protocol abstract object) 
// takes in ctor these 3 services + runtime configuration object: 
public Protocol1(IFramingAgent, IFramingAlgorithm, IFramingParser, configObject configuration) 

Моих объекты протокольных шпоночный зарегистрированы в качестве протокола. Кроме того, Каждая служба зарегистрирована ключом, потому что каждый протокол использует другой вид, который наследуется от одного и того же интерфейса. Конечно, все они зарегистрированы в качестве PerDependency (хотя я не очень понимаю разницу между этим LifeCycle против PerScope, был бы очень признателен объяснение)

А вот мой ужасный класс:

public class ProtocolsLayer : Layer 
{ 
    private IFrameworkDependencyResolver _resolver; 
    private IConfigurationService _configService; 

    public ProtocolsLayer(IFrameworkDependencyResolver resolver, IConfigurationService configurationService) 
    { 
     _resolver = resolver; 
     _configService = configurationService; 
    } 

    void HandleConnection1() 
    { 
     // What I have at the moment (terrible): 

     // Resolve the fitting services (All keyed - key is received by the type, Resolve and ResolveWithParameters used here are my wrappers) 
     var agent = _resolver.Resolve<IFramingAgent>(typeof(Protocol1FramingAgent)); 

     var algo = _resolver.Resolve<IFramingAlgorithm>(typeof(Protocol1FramingAlgorith)); 

     var parser = _resolver.Resolve<IFramingParser>(typeof(Protocol1FramingParser)); 

     // A parameter I get and pass to each protocol at runtime 
     var protocolConfig = _configService.GetConfig<Protocol1Configuration>(); 

     // Finally resolve the protocol with it's parameters: 

     protocol = _resolver.ResolveWithParameters<IProtocol>(typeof(Protocol1), new List<object>{ 
      agent, resolver, parser, protocolConfig 
     }); 

     //... 

     // Theres gotta be a better way!! 
    } 

    void HandleConntection2() 
    { 
     // Same as in protocol1 
    } 

    void HandleConnection3() 
    { 
     // Same as in protocol1 
    } 
} 

Имейте в виду, что я не хочу ссылаться на autofac, то есть я не могу использовать IIndex <> который я слышал.

Спасибо!

ответ

0

Вы должны позволить инфраструктуре инъекций зависимостей управлять instanciation.

Вы используете метод ResolveWithParameter, где эти параметры были разрешены инфраструктурой впрыска зависимостей. Это не требуется, и вы можете позволить структуре найти для вас зависимость:

Если Protocol1 нужен именованный параметр, вы можете указать его во время процесса регистрации.

builder.Register(c => c.Resolve<IConfigurationService>() 
         .GetConfig<Protocol1Configuration>()) 
     .As<Protocol1Configuration>(); 

builder.RegisterType<Protocol1>() 
     .Named<IProtocol1>(nameof(Protocol1)) 
     .WithParameter((pi, c) => pi.ParameterType == typeof(IFramingAgent), 
         (pi, c) => c.ResolveNamed<IFramingAgent>(nameof(Protocol1)) 
     .WithParameter((pi, c) => pi.ParameterType == typeof(IFramingAlgorithm), 
         (pi, c) => c.ResolveNamed<IFramingAlgorithm>(nameof(Protocol1)); 
builder.RegisterType<FramingAgentProtocol1>() 
     .Named<IFramingAgent>(nameof(Protocol1)); 
builder.RegisterType<FramingAlgorithmProtocol1>() 
     .Named<IFramingAlgorithm>(nameof(Protocol1)); 

Тогда ProtocolsLayer нужна только зависимость от IIndex<String, Func<IProtocol>> (или Func<Owned<Protocol1>>)

public class ProtocolsLayer 
{ 
    public ProtocolsLayer(IIndex<String, Func<IProtocol>> index) 
    { 
     this._index = index; 
    } 

    private readonly IIndex<String, Func<IProtocol>> _index; 

    public void HandleConnection1() 
    { 
     IProtocol protocol = this._index[nameof(Protocol1)](); 
    } 
} 

Если вы не хотите, чтобы ввести зависимость от IIndex<,> для всего вашего приложения вы можете ввести IProtocolFactory, который будет определен в время выполнения и создать реализацию только для проекта регистрации.

В Вашем проекте выполнения:

public interface IProtocolFactory 
{ 
    IProtocol Create(String protocolName) 
} 

В регистрационном проекте:

public class ProtocolFactory : IProtocolFactory 
{ 

    public ProtocolFactory(IIndex<String, IProtocol> index) 
    { 
     this._index = index; 
    } 

    private readonly IIndex<String, IProtocol> _index; 

    public IProtocol Create(String protocolName) 
    { 
     return this._index[typeof(TProtocol).Name]; 
    } 
}  

Тогда вы ProtocolsLayer класс будет выглядеть следующим образом:

public class ProtocolsLayer 
{ 
    public ProtocolsLayer(IProtocolFactory protocolFactory) 
    { 
     this._protocolFactory = protocolFactory; 
    } 

    private readonly IProtocolFactory _protocolFactory; 

    public void HandleConnection1() 
    { 
     IProtocol protocol = this._protocolFactory.Create("Protocol1"); 
    } 
} 

Вы также можете зарегистрировать Func<String, IProtocol> который будет называться решением IProtocol

ProtocolsLayer будет выглядеть следующим образом:

public class ProtocolsLayer 
{ 
    public ProtocolsLayer(Func<String, IProtocol> protocolFactory) 
    { 
     this._protocolFactory = protocolFactory; 
    } 

    private readonly Func<String, IProtocol> _protocolFactory; 

    public void HandleConnection1() 
    { 
     IProtocol protocol = this._protocolFactory("Protocol1"); 
    } 
} 

и регистрации, как это:

builder.Register(c => (String namedProtocol) => c.ResolveNamed<IProtocol>(namedProtocol) 
     .As<Func<String, IProtocol>>(); 

Но я не буду рекомендовать это решение, так как цель Func<String, IProtocol> protocolFactory зависимости не ясно. Наличие интерфейса IProtocolFactory облегчает понимание цели зависимости.

+0

Cyril спасибо! Не могли бы вы более подробно объяснить, как будет выглядеть этот IProtocolsFactory? Это звучит как идеальное решение для меня –

+0

@ S.Peter Я отредактировал мое сообщение, чтобы включить образец 'IProtocolFactory' –

+0

. Как я мог его использовать, чем без выдержки на IIndex <> –

 Смежные вопросы

  • Нет связанных вопросов^_^