Это правильный способ избежать шаблона ServiceLocator с помощью внедрения конструктора?

Это правильный способ избежать шаблона ServiceLocator с помощью внедрения конструктора?

public interface IEntitySomethingBase<TEntity>
{
    //Stuff
}

public class AccountEntitySomething : IEntitySomethingBase<Account>
{
    //Stuff
}

public class CustomerEntitySomething : IEntitySomethingBase<Customer>
{
    //Stuff
}

public class OrderEntitySomething : IEntitySomethingBase<Order>
{
    //Stuff
}
//Ditto, any number

Использование класса с помощью ServiceLocator, которого я хочу избежать.

public class MyConsumingClass
{
    public object DoSomething<TEntity>(TEntity entity)
        where TEntity : class
    {
        var thing = ServiceLocator.Current.GetInstance<IEntitySomethingBase<TEntity>>();
    }
}

Решение с использованием MEF. Измените выше *EntitySomething's для экспорта и

public class MyConsumingClass
{
    private List<Lazy<IEntitySomethingBase<Object>>> _things;

    [ImportingConstructor]
    public MyConsumingClass([ImportMany] List<Lazy<IEntitySomethingBase<Object>>> things)
    {
        _things = things;
    }

    public object DoSomething<TEntity>(TEntity entity)
        where TEntity : class
    {
        var thing = _things.Cast<IEntityInformationExtractor<TEntity>>().Where(t => t.GetType().FullName == entity.GetType().FullName).FirstOrDefault();
    }
}

На самом деле еще не пробовал, но задавался вопросом, есть ли другие способы добиться этого.

Благодарность


person jradxl    schedule 26.04.2012    source источник


Ответы (1)


Если я правильно понимаю, вам нужна фабрика

То, чего вы пытаетесь достичь, на самом деле стало очень обычным, и это потому, что контейнеры IoC разрешают зависимости при запуске приложения, а в большинстве приложений требуемые зависимости необходимо вводить на основе некоторых ограничений.

Современные контейнеры IoC пытаются решить эту проблему, например, Guice для Java.

Прочитайте это, чтобы получить больше информации о фабриках:

https://github.com/ninject/ninject.extensions.factory/wiki

Что вам нужно, так это фабрика для создания правильного типа на основе параметра, и вы можете сделать вызов своего локатора служб внутри своей фабрики (я знаю, что вы используете анти-шаблон локатора служб, но вы перемещаете его из своего домена к фабрике, фабрика используется только для подключения объектов, поэтому внутри фабрик часто вызываются вызовы IoC).

Для справки:

http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded

person Jupaol    schedule 27.04.2012