如何使用StructureMap注入在ASP.NET MVC为不同的环境不同的实例(S)? [英] How to inject different instance(s) for different context in ASP.NET MVC using StructureMap?

查看:96
本文介绍了如何使用StructureMap注入在ASP.NET MVC为不同的环境不同的实例(S)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用的是从类继承的注册表配置我们StructureMap容器​​在我们的ASP.NET MVC 4应用程序的启动。

从注​​册表类的一个部分摘录:

<$p$p><$c$c>For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeImplementation>();

我们想请根据背景下我们的接口的不同实例。的(例如,从数据库在线模式切换到维护模式,一切都保存在文件系统,因此使用其他接口(即库)遍布在我们的应用程序的地方)

例如默认情况下它应该使用 SomeImplementation ,但通过某种形式的查询字符串时,在URL(命名一个简单的背景的情况),应使用 SomeOtherImplementation

这怎么能对多个接口/类型的实现?

我们应该使用命名此实例?这样的:

<$p$p><$c$c>For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>().Named(\"other\");

我读到StructureMap的配置文件,但我不知道这是正确的道路要走。
我们是否应该使用这个配置文件?就像即:

 配置文件(其他,profileEx pression =&GT;
  {
     对于与所述; ISomeInterface&GT;()HybridHttpOrThreadLocalScoped()使用&lt;。SomeOtherImplementation&GT;();
  });

我们如何能够在飞行中切换不同的配置?

  ObjectFactory.Container.SetDefaultsToProfile(其他);

该方法是什么?的(在什么阶段MVC生命周期这样可以在最早发生?)

可这是只是当前请求或当前用户的会话临时切换?

在此先感谢!


解决方案

从我的经验,这样的运行时配置是使用的抽象工厂,负责在运行时创建的依赖。

这依赖可再与StructureMap登记,像这样:

您的注册表:

 公共类StorageRegistry:注册表
{
    公共StorageRegistry()
    {
        ...
        this.For&LT; IDataStoreInstance方式&gt;()使用(CTX =&GT; ctx.GetInstance&LT; D​​ataStoreAbstractFactory&GT;()ConfigureStorage());
        ...
    }
}

现在你的 DataStoreAbstractFactory 负责创建和配置的基础上配置必要的存储实例。由于 DataStoreAbstractFactory 现在与StructureMap注册你能注入必要的依赖将它确定要使用的存储方法。

实施例如:

 公共类DataStoreAbstractFactory
{
    公共DataStoreAbstractFactory()
    {
        //依赖弄清楚数据存储方法可以在这里注射。
    }    公共IDataStoreInstance ConfigureStorage()
    {
        //此方法可用于返回根据您的配置存储的类型(如:在线或维护)
    }
}公共接口IDataStoreInstance
{
    无效保存();
}公共类DatabaseStorage:IDataStoreInstance
{
    公共无效保存()
    {
        在数据库中的持久数据//实施细节
    }
}公共类FileStorage:IDataStoreInstance
{
    公共无效保存()
    {
        在一个文件系统中持续的数据//实施细节
    }
}

用法:

您控制器/服务或任何现在完全不知道他们正在使用访问和持久化数据什么时候存储方法。

 公共类UpdateController:控制器
{
    公共IDataStoreInstance StorageInstance {搞定;组; }    公共UpdateController(IDataStoreInstance storageInstance)
    {
        StorageInstance = storageInstance;
    }    [HttpPost]
    公众的ActionResult指数()
    {
        ...        this.StorageInstance.Save();        ...
    }    ...}

We are using classes inheriting from Registry to configure our StructureMap container in our ASP.NET MVC 4 application startup.

Some excerpt from one of the registry-classes:

For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeImplementation>();

We would like use different instances of our interfaces depending on the context. (For example switching from database "online" mode to "maintenance" mode where everything is saved on filesystem; therefore using other interfaces (i.e. repositories) all over the place in our application)

For example by default it should use SomeImplementation but when passing some kind of querystring in the url (to name a simple "context" scenario) it should use SomeOtherImplementation.

How can this be achieved for multiple interfaces/types?

Should we use named instances for this? Like:

For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>().Named("other");

I read about StructureMap Profiles but i'm not sure if this is the right way to go. Should we use profiles for this? Like i.e.:

Profile("other", profileExpression =>
  {
     For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>();
  });

How can we switch different configurations on the fly?

ObjectFactory.Container.SetDefaultsToProfile("other");

This way? (At what stage in mvc "life-cycle" this can happen at the earliest?)

Can this be a temporary switch for just the current request or current users session?

Thanks in advance!

解决方案

From my experience, runtime configuration like this is best achieved using an abstract factory that is responsible for creating your dependency during runtime.

This dependency can then be registered with StructureMap like so:

Your registry:

public class StorageRegistry : Registry
{
    public StorageRegistry()
    {
        ...
        this.For<IDataStoreInstance>().Use(ctx => ctx.GetInstance<DataStoreAbstractFactory>().ConfigureStorage());
        ...
    }
}

Now your DataStoreAbstractFactory is responsible for creating and configure the necessary storage instance based on your configuration. As DataStoreAbstractFactory is now registered with StructureMap you're able to inject the necessary dependencies into it for determining which storage method to use.

Implementation example:

public class DataStoreAbstractFactory
{
    public DataStoreAbstractFactory()
    {
        // Dependencies to figure out data storage method can be injected here.
    }

    public IDataStoreInstance ConfigureStorage()
    {
        // This method can be used to return type of storage based on your configuration (ie: online or maintenance)
    }
}

public interface IDataStoreInstance
{
    void Save();
}

public class DatabaseStorage : IDataStoreInstance
{
    public void Save()
    {
        // Implementation details of persisting data in a database
    }
}

public class FileStorage : IDataStoreInstance
{
    public void Save()
    {
        // Implementation details of persisting data in a file system
    }
}

Usage:

Your controller/services or whatever are now completely unaware of what storage method they're using when accessing and persisting data.

public class UpdateController : Controller
{
    public IDataStoreInstance StorageInstance { get; set; }

    public UpdateController(IDataStoreInstance storageInstance)
    {
        StorageInstance = storageInstance;
    }

    [HttpPost]
    public ActionResult Index()
    {
        ...

        this.StorageInstance.Save();

        ...
    }

    ...

}

这篇关于如何使用StructureMap注入在ASP.NET MVC为不同的环境不同的实例(S)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆