StructureMap 单例因参数而异?

发布于 2024-09-16 01:54:36 字数 361 浏览 3 评论 0原文

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

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

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

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

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

Using StructureMap, is it possible to have a singleton object for each value of an argument?
For example, say I want to maintain a different singleton for each website in a multi-tenancy web app:

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

I want to maintain a different singleton object corresponding to each site:

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

Currently, it seems to create a new object every time I try to resolve ISiteSettings.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奶气 2024-09-23 01:54:36

谢谢约书亚,我接受了你的建议。这是我完成的解决方案,看起来效果很好。任何反馈表示赞赏。

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>()
);

Thanks Joshua, I took your advice. Here's the solution I finished up with, which seems to work fine. Any feedback appreciated.

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;
        }
    }
}

With StructureMap configuration:

ObjectFactory.Initialize(
    x => x.For<ISiteSettings>()
        .LifecycleIs(new TenantLifecycle())
        .Use<SiteSettings>()
);
美男兮 2024-09-23 01:54:36

Singleton 作用域实际上意味着单例——只能有一个实例。对于您的场景,我建议您实现自定义 ILifecycle 它使用 requestHost (我假设可以从 HttpContext 中提取)来返回适当的缓存实例。查看 StructureMap 源代码,了解其他 ILifecycle 是如何实现的。

当您注册 For 时,可以选择指定您自己的 ILifecycle,而不是使用内置的 ILifecycle 之一。

The Singleton scope really means singleton - there can be only one instance. For your scenario, I would recommend you implement a custom ILifecycle which uses the requestHost (which I assume can be pulled out of HttpContext) to return the appropriate cached instance. Take a look at the StructureMap source code to see how the other ILifecycles are implemented.

When you register For<ISiteSettings>, there is an option to specify your own ILifecycle, instead of using one of the ones built in.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文