IoC / Dependency Injection - Как обрабатывать контекстные зависимости (используя Structuremap) - PullRequest
0 голосов
/ 17 июля 2011

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

В моем мультитенантном приложении файловая система абстрагируется и ограничивается областью для каждого арендатора. Поэтому, если службе требуется создавать файлы, мы внедряем экземпляр 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 :(
        }
    }

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

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

Идеи

1 Ответ

1 голос
/ 11 августа 2012

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

Примерный код:

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

    return container.GetInstance<TestMessageHandler>();
}

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

...