Unity:在application_BeginRequest中使用相同的数据上下文?

发布于 2024-08-10 17:02:29 字数 1926 浏览 3 评论 0原文

以前,我设法设置我的统一,以便每次向我的存储库项目提供一个新的 DataContext。效果很好。

但例如,我使用的 WCF 方法打开了 2 个服务,这两个服务又打开了 2 个存储库(存储库模式)。我希望能够在同一个 wcf 方法中重用相同的数据上下文。

所以我一直在查看RegisterInstance,但我检查了数据上下文的GetHashCode,并且每次都不同。我认为每次我假设我有一个实例设置时,Unity都会首先检查子容器 - 见下文

这是我执行一次的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,这一点非常重要。

当我处理我的存储库时,我正在处理数据上下文...现在(如果我可以让它工作)我想我需要在 EndRequest 中处理它。否则,如果一个服务完成并处理 DataContext 和另一个服务服务还没有完成,那么我就会遇到问题。

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

总结是每个 WCF 方法必须使用自己的 datacontext ,一个 Web 方法可以调用多个服务(存储库模式),而该服务又将调用其存储库,该存储库需要构造函数上的数据上下文哪个统一注册 - 但目前在同一个 WCF 方法中,多个服务调用那里的存储库,并且它们获得自己的 DataContext。

如果我可以澄清任何事情,请告诉我

谢谢

编辑

忘记提及我如何团结起来解决问题......我简单地将容器(不是子容器)上的这个调用到服务上调用存储库

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

Previously i managed to setup my unity to provide a new DataContext each time to my Repository project. It works great.

But for example, I am in a WCF method which opens up 2 services which in turn opens up 2 repositories (repository pattern).. i was hoping to be able to reuse the same datacontext within the same wcf method.

So i have been looking at RegisterInstance but i check the GetHashCode of the datacontext and its different each time. i thought unity will check the child container first every time which i presume i have an instance setup - see below

Here is my unity that executes once!

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

And then i try and configure in global.asax under Application_BeginRequest - but maybe this is not ideal as it seems to enter multiple times.. even when running the wcf service before someone calls a wcf method

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

And here is my 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
        }
    }

As i say in my WCF method i am opening 2 services which in turn opens up "THEIR OWN" Respository which takes in a DataContext - MyDataContext

To fix the problem with the BeginRequest i could register the datacontext as an instance (if it worked :-) ) on every WCF method i have but it seems a bit of a long way round.

Of course its very imported that each connection (not sessions) gets its own DataContext.

I was disposing the datacontext when when i disposed of my repository ... now (if i can get it working) i presume i will need to dispose of this in EndRequest.. otherwise if one service completes and disposes of the DataContext and the other service hasn't finsihed then i am going to get issues.

I hope i have explained this well, :-)

Summary is that each WCF method must use its own datacontext , a web method can call more than 1 service (repository pattern) which in turn will call its repository which expects a datacontext on the constuctor which unity Registers - but currently when in the same WCF method, multiple services call there repositories and they get there own DataContext.

If i can clarify anything please let me know

Thanks

EDIT

Forgot to mention how i am getting unity to resolve things ... I simple call this on the container (not child container) to the service which in turn calls the respository

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

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

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

发布评论

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

评论(1

银河中√捞星星 2024-08-17 17:02:29

您正在子容器中注册实例,因此在解析服务时必须使用子容器(此外,您应该在 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);
        }
    }
}

You are registering the instance in the child container, so you have to use the child container when resolving your service (Also, you should be disposing of your child container on Application_EndRequest):

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

However, using a PerRequestLifetimeManager should accomplish the same thing:

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

Here's how I implement it:

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