关键类需要Session(或其他特定于上下文的变量)时,如何设置IoC [英] How to set up IoC when a key class needs Session (or other context-specific variable)

查看:112
本文介绍了关键类需要Session(或其他特定于上下文的变量)时,如何设置IoC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出在依赖类可以根据应用程序中的某个变量(在这种情况下是会话状态)来更改的情况下如何使用IoC。例如,我们的每个客户端都有不同的数据库,所以与数据库的连接需要建立在存储在其Session中的值上(特别是因为某些用户可能拥有多个数据库,如果他们拥有多个业务,并且在数据库之间切换) 。

I am trying to figure out how to use IoC in situations where the dependent classes can change based on some variable in the application (in this case, Session state). For example, each of our clients have a different database, so the connection to the database needs to be built on a value stored in their Session (particularly since some users could have multiple databases if they own multiple businesses, and would switch between databases).

以下是我们目前如何设置此结构的通用示例:

Here is a generic example of how we'd currently set up this structure:

public class MyTestController : ControllerBase
{
    Repository _rep;

    public MyTest(Repository rep)
    {
        _rep = rep;
    }

    public MyTest()
    {
        string connString = String.Format("Server={0}; Database={1};"
            , SessionContainer.ServerName, SessionContainer.DatabaseName;
        var dc = new DataContext(connString);
        _rep = new Repository(dc);
    }

    public int SampleFn()
    {
        return _rep.GetCountOfEmployees();
    }
}

public class Repository
{
    DataContext _context;

    public Repository(DataContext context)
    {
        _context = context;
    }
} 

我们是否可以使用IoC进行设置,并消除默认值?如果是这样,我没有使用DI这样,但我想探索一个StructureMap或Unity的可能性(注意:我们通常将db / server传递给构建数据文件的工厂类...上面的例子只是为了简洁起见)。 >

Would we be able to set this up using IoC and eliminate the default c-tors? If so, how? I don't have a problem just using D.I. like this, but I'd like to explore the possibility of a StructureMap or Unity (note: we normally pass in db/server to a factory class that builds the datacontext ... above example is just for brevity).

推荐答案

如何创建存储库实例及其生命周期,与Controller无关。

How the Repository instance is created, as well as its lifetime, is of no concern of the Controller.

当您在容器中注册组件时,应指定组件的生命周期。根据您的实现情况,您可以选择将存储库的生命周期设置为跟随会话。

When you register components in the container, you should specify the lifetime of the component. Depending on your implementation, you may simply choose to set the lifefime of the Repository to follow the session.

无论如何,您可以使用工厂从会话,但是从控制器外部执行此操作。

In any case you could use a factory to create the repository from the session, but do this from outside the Controller.

您绝对需要摆脱默认构造函数。

You definitely need to get rid of the default constructor.

在我的头顶我不记得如何在Unity或StructureMap中这样做,所以这里是一个城堡温莎的例子。

Off the top of my head I can't remember how to do this in Unity or StructureMap, so here's a Castle Windsor example.

定义抽象工厂:

public interface IRepositoryFactory
{
    Repository Create();
}

和一个实现

public class MyRepositoryFactory : IRepositoryFactory
{
    private readonly HttpContextBase httpContext;

    public MyRepositoryFactory(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        this.httpContext = httpContext;
    }

    #region IRepositoryFactory Members

    public Repository Create()
    {
        // return Repository created from this.httpContext
    }

    #endregion
}

现在注册全部东西

container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IRepositoryFactory>()
    .ImplementedBy<MyRepositoryFactory>()
    .LifeStyle.PerWebRequest);
container.Register(Component.For<Repository>()
    .UsingFactory((IRepositoryFactory f) => f.Create())
    .LifeStyle.PerWebRequest);

这里我使用了PerWebRequest的生活方式,但如果要优化,可能需要创建一个PerWebSession定制生活方式。这不是很难在城堡,但我不记得在其他DI容器有多困难。

Here I've used the PerWebRequest lifestyle, but if you want to optimize you might want to create a custom PerWebSession lifestyle. This is not too hard to do in Castle, but I can't remember how hard it is in other DI Containers.

您还需要注册HttpContextBase,因为MyRepositoryFactory取决于它。

You will also need to register HttpContextBase, since MyRepositoryFactory depends on it.

这篇关于关键类需要Session(或其他特定于上下文的变量)时,如何设置IoC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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