Контейнер IoC, встроенный в проект - PullRequest
6 голосов
/ 23 января 2012

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

Причина этого в том, что я пишу инфраструктуру и хотел бы предоставить один файл .dll без каких-либо дополнительных зависимостей.

Я тоже не хочу, чтобы ILMerge моей сборки со сборкой IoC ..

Я думал о MEF, другие предложения?

Ответы [ 4 ]

3 голосов
/ 23 января 2012

Если вам не нужно ничего необычного, контейнер DI может быть очень коротким:

public class Container
{
   private readonly Dictionary<Type,Func<Container,object>> factories;
   private readonly Dictionary<Type,object> cache;

   public Container()
   {
       this.factories = new Dictionary<Type,Func<Container,object>>();
       this.cache = new Dictionary<Type,object>();
   }

   public void Register<TContract>(Func<Container,TContract> factory)
   {
       // wrap in lambda which returns object instead of TContract
       factories[typeof(TContract)] = c => factory(c);
   }

   public TContract Get<TContract>()
   {
       var contract = typeof(TContract);
       if (!cache.ContainsKey(contract))
       {
           this.cache[contract] = this.factories[contract](this);
       }
       return (TContract)this.cache[contract];
   }
}

Что бы вы использовали, как это:

var container = new Container();
container.Register<ICar>(c => new Car(
    c.Get<IEngine>(), c.Get<IWheel>()));
container.Register<IWheel>(c => new Wheel());
container.Register<IEngine>(c => new Engine());

var car = container.Get<ICar>();

Еще более минималистичным было бы сделать внедрение зависимостей без контейнера:

IWheel wheel = new Wheel();
IEngine engine = new Engine();
ICar car = new Car(engine, wheel);

Однако для сложных графов объектов может быстро усложниться поддержание правильного порядка построения во время рефакторингов. Контейнер не имеет этой проблемы.

3 голосов
/ 23 января 2012

Если вы используете .NET 4.0, у вас есть MEF.

Для .NET 2 я однажды написал нечто подобное, используя интерфейсы и Reflection. Существует множество учебных пособий, описывающих этот процесс. Даже если вы можете использовать MEF, все же стоит попробовать некоторые учебники по отражению, так как именно так MEF работает под ним.

Также проверьте этот вопрос, на который есть несколько хороших ответов. TinyIoC выглядит просто как один исходный файл.

0 голосов
/ 23 января 2012

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

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

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

0 голосов
/ 23 января 2012

Мне очень нравится Castle.Windsor с открытым исходным кодом, так что вы можете добавить соответствующие файлы кода в свой проект

...