IoC /依赖注入 - 如何处理上下文依赖关系(使用Structuremap)

时间:2011-07-17 18:04:34

标签: c# dependency-injection inversion-of-control structuremap multi-tenant

在我的应用程序中引入消息后,似乎我发现了一点气味。

在我的多租户应用程序中,文件系统被抽象并为每个租户确定范围。因此,如果服务需要创建文件,那么我们将注入一个IFileSystem实例,该实例将作用于租户目录/容器。

这是通过配置structuremap以通过获取具有当前用户站点的上下文对象来构造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 个答案:

答案 0 :(得分:1)

您可以use nested containers并将嵌套容器配置为具有上下文的虚拟实现。

代码大约是:

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

    return container.GetInstance<TestMessageHandler>();
}

这应该设置ISiteContext的自定义(虚拟)实现,而不覆盖全局容器(ObjectFactory.Container)。当然,如果没有更多信息,我无法为您提供DummyContext的适当实施。但这应该让你开始。