Unity:在application_BeginRequest中使用相同的datacontext?

时间:2009-11-08 22:35:47

标签: wcf linq-to-sql dependency-injection unity-container datacontext

以前我设法设置我的统一,每次都为我的Repository项目提供一个新的DataContext。它很棒。

但是,例如,我在一个WCF方法中打开了2个服务,这反过来又打开了2个存储库(存储库模式)..我希望能够在同一个wcf方法中重用相同的datacontext。

所以我一直在看RegisterInstance,但我每次检查datacontext的GetHashCode及其不同。我认为Unity会每次都检查子容器,我认为我有一个实例设置 - 见下文

这是我执行一次的团结!

container.RegisterType<MyDataContext>(new TransientLifetimeManager(),
      new InjectionConstructor())

然后我尝试在Application_BeginRequest下的global.asax中配置 - 但是这可能是不理想的,因为它似乎进入多次..即使在有人调用wcf方法之前运行wcf服务

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        Bootstrapper.ConfigureDataContextContainer();
    }

这是我的configureDataContextContainer

    public static void ConfigureDataContextContainer()
    {
        if (childContainer == null) // I have to do this otherwise it executes multiple times.
        {
            childContainer = Bootstrapper.Container.CreateChildContainer();
            childContainer.RegisterInstance<MyDataContext>
(container.Resolve<MyDataContext>());  // I Presume i create an instance here
        }
    }

正如我在我的WCF方法中所说,我打开了2个服务,这反过来打开了“他们自己”的存储库,它接收了一个DataContext - MyDataContext

要解决BeginRequest的问题,我可以在我拥有的每个WCF方法上将datacontext注册为一个实例(如果它工作:-)),但它看起来有点长。

当然,它是非常导入的,每个连接(不是会话)都有自己的DataContext。

当我处理我的存储库时,我正在处理datacontext ...现在(如果我可以使它工作)我假设我将需要在EndRequest中处理它...否则如果一个服务完成并处理DataContext而其他服务还没有完善,那么我就会遇到问题。

我希望我已经很好地解释了这一点: - )

总结是每个WCF方法必须使用自己的datacontext,一个web方法可以调用多个服务(存储库模式),而这个服务又将调用其存储库,该存储库期望构造器上的datacontext统一注册 - 但目前处于相同的WCF方法,多个服务调用存储库,并且它们获得自己的DataContext。

如果我能澄清一切,请告诉我

由于

修改

忘了提到我如何统一解决问题...我简单地在容器(而不是子容器)上调用它来服务,而服务又调用存储库

  using (IOfficeService officeService = Bootstrapper.Container.Resolve<IOfficeService >())
        {

1 个答案:

答案 0 :(得分:3)

您正在子容器中注册实例,因此在解析服务时必须使用子容器(另外,您应该在Application_EndRequest上处理子容器):

using (var service = childContainer.Resolve<IOfficeService >())
{
}

但是,使用PerRequestLifetimeManager应该完成同样的事情:

Container.RegisterType<MyDataContext>(new PerRequestLifetimeManager());

以下是我如何实施它:

public class PerRequestLifetimeManager : LifetimeManager {
    private Guid key;

    public PerRequestLifetimeManager() {
        key = Guid.NewGuid();
    }

    public override object GetValue() {
        if (HttpContext.Current == null) {
            return null;
        } else {
            return HttpContext.Current.Items[key];
        }
    }

    public override void RemoveValue() {
        if (HttpContext.Current != null) {
            HttpContext.Current.Items.Remove(key);
        }
    }

    public override void SetValue(object newValue) {
        if (HttpContext.Current != null) {
            HttpContext.Current.Items.Add(key, newValue);
        }
    }
}