3

Привет в Autofac Я abble сделать это:StructureMap питания Строка параметров конструктору при запросе экземпляра

public class Service1_Client 
{ 
    private const string ServiceName = "Service1"; 
    Func<string, RabitMqClient> _clientFunc; 

    public Service1_Client(Func<string, RabitMqClient> clientFunc) 
    { 
     _clientFunc = clientFunc; 
    } 

    public IList<object> GetData() 
    { 
     return _clientFunc(this.ServiceName).Get<IList<object>>();    
    } 
} 

public class Service2_Client 
{ 
    private const string ServiceName = "Service2"; 
    Func<string, RabitMqClient> _clientFunc; 

    public Service2_Client(Func<string, RabitMqClient> clientFunc) 
    { 
     _clientFunc = clientFunc; 
    } 

    public IList<object> GetData() 
    { 
     return _clientFunc(this.ServiceName).Get<IList<object>>();    
    } 
} 

public class RabitMqClient 
{ 
    private IConnectionFactory _connectionFactory; 
    private string _baseServiceName; 
    public RabitMqClient(IConnectionFactory connectionFactory, string baseServiceName) 
    { 
     _connectionFactory = connectionFactory; 
     _baseServiceName = baseServiceName; 
    } 

    public TResult Get<TResult>() 
    { 
     string topicName = this.GetTopicName(); 
     ///Connect to the channel that uses the topic and ask for data... 
    } 

    private string GetTopicNAme() 
    { 
     /// this should be an algoritam for getting the topic from the speccified baseServiceName (I have omitted the details) 
     return this._baseServiceName; 
    }  
} 

Теперь объяснение: В принципе у меня есть класс (RabitMqClient), который зависит от 2-х параметров:

  1. ConnectionFactory (IConnectionFactory)
  2. baseServiceName (строка)

Эти параметры используются для подключения к серверу RabbitMq. Теперь я использую Темы в RabbitMq для диверсификации сервисов и для получения правильной темы используется строковый параметр baseServiceName. Ожидается, что вызывающий (Service1_Client, Service2_Client) будет предоставлять строковый параметр baseServiceName.

В Autofac я могу зарегистрировать этот класс, как это:

builder.Register((context, parameters) => 
{ 
    var param = parameters.First() as Autofac.TypedParameter; 
    return new HcRabbitMqClient(
     context.Resolve<IConnectionFactory>(),param.Value.ToString()); 
}).AsSelf().InstancePerDependency(); 

Это говорит Autofac, что при запросе этого класса, пусть Autofac разрешить первый параметр, но Caller поставит второй параметр (строка) в сайт вызова. Этот строковый параметр затем будет помещен в значение параметров. Использование этого можно увидеть в приведенном выше коде (Service1_Client, Service2_Client) GetData();

Как это сделать в StructureMap?

+0

Можете ли вы дать немного больше информации о том, как это используется в вашем приложении с Autofac, пожалуйста? –

ответ

1

насчет расширения этой фабричной модели?

public interface IRabitMqClientFactory 
{ 
    IRabitMqClientFactory Create(string baseServiceName); 
} 

public class RabitMqClientFactory : IRabitMqClientFactory 
{ 
    public RabitMqClientFactory(IConnectionFactory connectionFactory){ 
     _connectionFactory = connectionFactory; 
    } 

    public IRabitMqClientFactory Create(string baseServiceName) 
    { 
     _baseServiceName = baseServiceName; 
    } 
} 

, а затем просто

public class Service1_Client 
{ 
    private const string ServiceName = "Service1"; 
    private RabbitMqClient _rabbitMqClient; 

    public Service1_Client(IRabitMqClientFactory rabitMqClientFactory) 
    { 
     _rabbitMqClient = rabitMqClientFactory.Create(ServiceName); 
    } 

    public IList<object> GetData() 
    { 
     return _rabbitMqClient.Get<IList<object>>();    
    } 
} 

это также немного более читаемым, чем иметь сложную логику внутри IoC.

+0

Хорошо, это решение даже лучше, чем в моем примере. благодаря – Luka

1

Попробуйте
For<Func<string, RabitMqClient>>().Use(cstr => new RabitMqClient(cstr));

+1

Хорошо, это работает для 1 параметра, но что, если у меня больше? т.е. Func Luka

+0

Затем добавьте парметры, такие как 'For >(). Используйте ((cstr, int) => {return new RabitMqClient (cstr, int)}); ' – Bucketcode