IoC / Dependency Injection — как обрабатывать контекстные зависимости (используя Structuremap)

После введения обмена сообщениями в моем приложении кажется, что я нашел что-то вроде запаха.

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

Это достигается за счет настройки структуры структуры для создания реализации IFileSystem путем получения контекстного объекта, который имеет текущий сайт пользователя.

Теперь нам нужно использовать файловую систему, когда нет контекста и текущего пользователя (в фоновом потоке). Вот простой пример:

    public class SiteContext
    {
        public string SiteId { get { return "Site123"; } }
    }

    public class FileSystemSettings
    {
        public string BaseDirectory { get; set; }
    }

    public interface IFileSystem { }

    public class DefaultFileSystem : IFileSystem
    {
        public DefaultFileSystem(FileSystemSettings settings)
        {

        }
    }

    public interface ISomeService { }

    public class SomeService : ISomeService
    {
        public SomeService(IFileSystem fileSystem)
        {

        }
    }

    public class TestMessageHandler : IMessageHandler<TestMessage>
    {
        public TestMessageHandler(ISomeService someService)
        {
            // oO we don't have access to site context here :(
        }
    }

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

Однако даже для этого мне все равно потребовалось бы создавать объект ISomeService вручную, что является проблемой, поскольку некоторые из моих служб имеют ряд зависимостей = множество вызовов ObjectFactory.GetInstance...

Идеи?


person Ben Foster    schedule 17.07.2011    source источник
comment
stackoverflow.com/questions/1943576/   -  person Mark Seemann    schedule 18.07.2011
comment
Можете уточнить вопрос? Как вы собираетесь использовать SiteContext? Покажите код, который работает, и укажите код, который не работает.   -  person Joshua Flanagan    schedule 18.07.2011


Ответы (1)


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

Код будет примерно таким:

using (var container = ObjectFactory.Container.GetNestedContainer())
{
    container.Configure(config => {
        config.For<ISiteContext>().Use<DummyContext>();
    });

    return container.GetInstance<TestMessageHandler>();
}

Это должно установить пользовательскую (фиктивную) реализацию ISiteContext без перезаписи глобального контейнера (ObjectFactory.Container). Конечно, я не могу дать вам подходящую реализацию DummyContext без дополнительной информации. Но это должно заставить вас начать.

person kelloti    schedule 11.08.2012