StructureMap单例因参数而异吗?

时间:2010-08-27 06:05:57

标签: .net asp.net-mvc dependency-injection inversion-of-control structuremap

使用StructureMap,是否可以为参数的每个值设置一个单独的对象? 例如,假设我想为多租户网络应用中的每个网站维护一个不同的单例:

For<ISiteSettings>().Singleton().Use<SiteSettings>();

我想维护一个与每个站点对应的不同单例对象:

ObjectFactory.With<string>(requestHost).GetInstance<ISiteSettings>();

目前,每当我尝试解析ISiteSettings时,它似乎都会创建一个新对象。

2 个答案:

答案 0 :(得分:5)

谢谢约书亚,我接受了你的建议。这是我完成的解决方案,似乎工作正常。任何反馈意见。

public class TenantLifecycle : ILifecycle
{
    private readonly ConcurrentDictionary<string, MainObjectCache> _tenantCaches =
        new ConcurrentDictionary<string, MainObjectCache>();

    public IObjectCache FindCache()
    {
        var cache = _tenantCaches.GetOrAdd(TenantKey, new MainObjectCache());
        return cache;
    }

    public void EjectAll()
    {
        FindCache().DisposeAndClear();
    }

    public string Scope
    {
        get { return "Tenant"; }
    }

    protected virtual string TenantKey
    {
        get
        {
            var requestHost = HttpContext.Current.Request.Url.Host;
            var normalisedRequestHost = requestHost.ToLowerInvariant();
            return normalisedRequestHost;
        }
    }
}

使用StructureMap配置:

ObjectFactory.Initialize(
    x => x.For<ISiteSettings>()
        .LifecycleIs(new TenantLifecycle())
        .Use<SiteSettings>()
);

答案 1 :(得分:4)

Singleton范围实际上意味着单例 - 只能有一个实例。对于您的场景,我建议您实现一个自定义ILifecycle,它使用requestHost(我假设可以从HttpContext中取出)来返回相应的缓存实例。查看StructureMap源代码,了解其他ILifecycles的实现方式。

当您注册For<ISiteSettings>时,可以选择指定您自己的ILifecycle,而不是使用其中一个内置的。