Как установить данное свойство, когда экземпляр класса, который реализует данный интерфейс, создан с использованием Unity - PullRequest
1 голос
/ 15 февраля 2012

Учитывая этот упрощенный сценарий:

public interface IRepository
{
    string ConnectionString { get; set; }
}

public abstract class Repository : IRepository
{
    public string ConnectionString { get; set; }
}

public class CustomerRepository : Repository, ICustomerRepository
{
}

public class OrderRepository : Repository, IOrderRepository
{
}

и следующие регистрации Unity:

IUnityContainer container = new UnityContainer();
container.RegisterType<ICustomerRepository, CustomerRepository>();
container.RegisterType<IOrderRepository, OrderRepository>();

Каков рекомендуемый способ перехватить создание любого экземпляра IRepository для установки значения для свойства ConnectionString (и, соответственно, для любого другого свойства).

ОБНОВЛЕНИЕ 1: Этот пост не о шаблонных шаблонах или альтернативном решении, включающем перефакторинг исходных классов. Это Unity и лучший способ установить свойство, перехватывая создание экземпляров, реализующих данный интерфейс.

Ответы [ 3 ]

0 голосов
/ 16 февраля 2012

Поскольку вам нужны строки подключения от разных провайдеров (как вы упомянули в своем комментарии). Я хотел бы предложить небольшое изменение в дизайне, вы можете добавить новую зависимость, такую ​​как IConnectionStringProvider

public interface IConnectionStringProvider 
{
    string GetConnectionString(); 
}

Затем обновите IRepository

public interface IRepository  
{    
        IConnectionStringProvider ConnectionStringProvider  {get; set;}
        string ConnectionString { get; } // no set is required 
 }

public abstract class Repository : IRepository     
   {       
         IConnectionStringProvider ConnectionStringProvider  {get; set;}
         public string ConnectionString 
           { 
              get 
                 {
                    return ConnectionStringProvider.GetConnectionString(); 
                 }
            }
   }    

Затем вы можете использовать единство для ввода правильного поставщика строки подключения в соответствии с вашими потребностями

container.RegisterType<IConnectionStringProvider , ConnectionStringProvider>();
0 голосов
/ 16 февраля 2012

Ваши репозитории не должны отвечать за создание соединения.

  1. Вы нарушаете принцип единой ответственности
  2. Вы получили дублированный код = сложнее поддерживать код в будущем.
  3. Что вы делаете, если хотите разделить соединение между вашими репозиториями?

Решение:

Создать IConnectionFactory (которыйреализацию вы можете зарегистрировать как экземпляр / singleton) и использовать ее в качестве зависимости в своих репозиториях.

Обновление 1

Вы можете использовать InjectionProperty.Найдите строку подключения на линии перед ее настройкой.

Обновление 2:

Используйте фабрики для настройки хранилищ: http://www.pnpguidance.net/post/RegisteringFactoryMethodCreateObjectsUnityStaticFactoryExtension.aspx

Что-токак:

container.Configure<IStaticFactoryConfiguration>()
    .RegisterFactory<ICustomerRepository>
    (new FactoryDelegate(c => 
       { 
          var repos = new CustomerRepository();
          repos.ConnectionString = yourComPlus.ConnectionString;
          return repos;
       }
    ));
0 голосов
/ 16 февраля 2012

Если вы сделаете connectionString параметр конструктора, конфигурация будет выглядеть следующим образом

container.RegisterType<ICustomerRepository, CustomerRepository>(new InjectionConstructor("myConnStr1");

Для внедрения свойства конфигурация будет

container.RegisterType<IOrderRepository, OrderRepository>(new InjectionProperty("ConnectionString", "myConnStr2");

[Обновить] Проект TecX в кодовом комплексе содержит порт Виндзорского замка Типизированные производственные мощности .Это позволяет зарегистрировать фабричный интерфейс, который принимает параметры.

public interface ICustomerRepositoryFactory
{
  ICustomerRepository Create(string connectionString);
}

container.RegisterType<ICustomerRepositoryFactory>(new TypedFactory());
container.RegisterType<ICustomerRepository, CustomerRepository>(new InjectionProperty("ConnectionString");

Если вы разрешите фабричный интерфейс и вызовете метод Create, он отобразит параметр метода в соответствующий параметр конструктора. [Update2] Он еще не поддерживает внедрение свойств (пока нет. Попросите еще раз завтра) .Он также поддерживает внедрение свойств, но вам нужно будет пометить свойство для внедрения при регистрации типов репозитория. [/ Update2] Вам не нужно будет реализовывать фабрику.Расширение делает это за вас.

...