Structuremap (или любой IoC, действительно) вопрос архитектуры - PullRequest
0 голосов
/ 03 декабря 2009

Я собираюсь использовать structmap для проекта, над которым я работаю. Основная суть в том, что у меня есть шаблон репозитория с реализацией NHibernate, но я хочу использовать StructureMap для загрузки репозиториев на случай, если я когда-нибудь решу переключиться на Linq2Sql или другой тип реализации. Я знаю, как инициализировать структурную карту, но мой вопрос - где? Должно ли веб-приложение, использующее мою библиотеку, отвечать за настройку реестра? Должен ли я иметь реализацию по умолчанию в моей библиотеке? Где бы это подошло лучше всего?

Моя структура библиотеки на данный момент выглядит следующим образом:

  • Library.Data
  • Library.Data.NHibernate
  • Library.Domain

Пространство имен .Domain содержит фактические сущности, а пространство имен .Data содержит интерфейсы для хранилища. Пространство имен .Data.NHibernate содержит реализацию этих интерфейсов NHibernate.

Ответы [ 3 ]

2 голосов
/ 03 декабря 2009

У меня был тот же вопрос некоторое время назад, и, наконец, я закончил создание класса реестра для каждого проекта и вызывал их каскадно.

Я обновлю код, когда вернусь домой.

Обновление

У меня было 3 проекта (Web, Services и Data), но я не хотел, например, добавлять ссылку на Data в мой Web-проект, поэтому я сделал так, что каждый проект отвечает за регистрацию своих собственных интерфейсов.

Например, в моем веб-проекте я создал класс WebRegistry, который не только регистрирует свои собственные типы, но также вызывает класс ServicesRegistry в моем проекте Services и так далее.

WebRegistry:

public class WebRegistry : Registry
{
    public WebRegistry()
        {
            ObjectFactory.Configure(x =>
            {
                //call to ServicesRegistry in my services project
                x.AddRegistry(new ServicesRegistry());

                //Register your web classes here
                ForRequestedType... blablablabla

            });

        }
}

ServicesRegistry:

public class ServicesRegistry : Registry
{
    public ServicesRegistry()
    {
        ObjectFactory.Configure(x =>
        {
            x.AddRegistry(new DataRegistry());

            //Register your services classes here
            ForRequestedType... blablablabla
        });

    }
}

И, наконец, DataRegistry:

public class DataRegistry : Registry
{
    public DataRegistry()
    {
        ObjectFactory.Configure(x =>
        {
            ForRequestedType blablbabla....

        });
    }
}

Я думаю, что в этом случае все совершенно идеально, и вам нужно всего лишь один вызов веб-реестра в вашем global.asax для настройки всего приложения:

/// <summary>
/// 
/// </summary>
public class Bootstrapper
{

    /// <summary>
    /// 
    /// </summary>
    public static void ConfigureStructureMap()
    {
        ObjectFactory.Initialize(x =>
        {
            x.AddRegistry(new WebRegistry());
        });
    }


}

Global.asax:

    protected void Application_Start()
    {

        Bootstrapper.ConfigureStructureMap();


    }
2 голосов
/ 03 декабря 2009

При использовании контейнеров IoC вызывающее приложение в идеале должно отвечать за настройку всех зависимостей.

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

Я не совсем уверен, что вы подразумеваете под реализацией "по умолчанию" в контексте вашей библиотеки. Ваша реализация по умолчанию (настроенная вашим реестром StructureMap) будет тем экземпляром, который вы получите, когда попросите StructureMap реализовать данный интерфейс (предположительно, в вашем случае IRepository) без указания каких-либо других критериев.

Для вас вы хотите, чтобы этот экземпляр был настроен как ваша реализация NHibernate. Предположительно, эта реализация уже находится в пространстве имен Library.Data.NHibernate как ваш "репозиторий NHibernate". Вам не нужно создавать какую-либо другую реализацию, если вы не хотите изменить IRepository реализацию на что-то другое.

0 голосов
/ 13 декабря 2009

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

Если вы хотите сделать это в вызывающей сборке (которая связывает его с инструментом IOC), просто сделайте это в Global.asax.cs или в вызываемом там классе.

Если вы хотите сделать это в другой сборке, используйте модуль HTTP, например так: http://codecampserver.googlecode.com/svn/trunk/src/DependencyResolution/DependencyRegistrarModule.cs

...