dependency-injection castle windsor - Ioc / DI - Почему мне нужно ссылаться на все слои / сборки в приложении ввода?




2 Answers

Если бы я не использовал контейнер DI, мне не пришлось бы ссылаться на библиотеку EntityFramework в моем приложении MVC3, только на моем бизнес-уровне, который ссылался бы на мой уровень DAL / Repo.

Да, это именно та ситуация, в которой DI так трудно избежать :)

С тесно связанным кодом каждая библиотека может иметь только несколько ссылок, но у них снова есть другие ссылки, создающие глубокий график зависимостей, например:

Поскольку граф зависимостей является глубоким, это означает, что большинство библиотек перетаскивают множество других зависимостей - например, на диаграмме библиотека C перетаскивает библиотеку H, библиотеку E, библиотеку J, библиотеку M, библиотеку K и библиотеку N. Это затрудняет повторное использование каждой библиотеки независимо от остальных - например, при модульном тестировании .

Однако в слабо связанном приложении, перемещая все ссылки на Корень композиции , граф зависимостей сильно сглажен :

Как показано зеленым цветом, теперь можно повторно использовать библиотеку C, не перетаскивая любые нежелательные зависимости.

Тем не менее, все, что было сказано, со многими контейнерами DI, вам не нужно добавлять жесткие ссылки на все необходимые библиотеки. Вместо этого вы можете использовать последнее связывание либо в форме условно-ориентированного сборочного (предпочтительного), либо для XML-конфигурации.

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

documentation register

(В связи с этим вопросом, EF4: Почему создание прокси-сервера должно быть включено, когда включена ленивая загрузка? ).

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

Если бы я не использовал контейнер DI, мне не пришлось бы ссылаться на библиотеку EntityFramework в моем приложении MVC3, только на моем бизнес-уровне, который ссылался бы на мой уровень DAL / Repo.

Я знаю, что в конце дня все библиотеки DLL включены в папку bin, но моя проблема заключается в том, чтобы явно ссылаться на нее через «добавить ссылку» в VS, чтобы иметь возможность публиковать WAP со всеми необходимыми файлами.




Если бы я не использовал контейнер DI, мне не пришлось бы ссылаться на библиотеку EntityFramework в моем приложении MVC3, только на моем бизнес-уровне, который ссылался бы на мой уровень DAL / Repo.

Вы можете создать отдельный проект под названием «DependencyResolver». В этом проекте вы должны ссылаться на все свои библиотеки.

Теперь для слоя UI не требуется NHibernate / EF или любая другая не соответствующая UI библиотека, за исключением ссылки Castle Windsor.

Если вы хотите скрыть замок Windsor и DependencyResolver со своего уровня пользовательского интерфейса, вы можете написать HttpModule, который вызывает материал реестра IoC.

У меня есть только пример для StructureMap:

public class DependencyRegistrarModule : IHttpModule
{
    private static bool _dependenciesRegistered;
    private static readonly object Lock = new object();

    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, args) => EnsureDependenciesRegistered();
    }

    public void Dispose() { }

    private static void EnsureDependenciesRegistered()
    {
        if (!_dependenciesRegistered)
        {
            lock (Lock)
            {
                if (!_dependenciesRegistered)
                {
                    ObjectFactory.ResetDefaults();

                    // Register all you dependencies here
                    ObjectFactory.Initialize(x => x.AddRegistry(new DependencyRegistry()));

                    new InitiailizeDefaultFactories().Configure();
                    _dependenciesRegistered = true;
                }
            }
        }
    }
}

public class InitiailizeDefaultFactories
{
    public void Configure()
    {
        StructureMapControllerFactory.GetController = type => ObjectFactory.GetInstance(type);
          ...
    }
 }

DefaultControllerFactory не использует контейнер IoC напрямую, но он делегирует методам контейнера IoC.

public class StructureMapControllerFactory : DefaultControllerFactory
{
    public static Func<Type, object> GetController = type =>
    {
        throw new  InvalidOperationException("The dependency callback for the StructureMapControllerFactory is not configured!");
    };

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return base.GetControllerInstance(requestContext, controllerType);
        }
        return GetController(controllerType) as Controller;
    }
}

Делегат GetController устанавливается в реестр StructureMap (в Виндзоре он должен быть установщиком).




Related