对于 Windows 应用程序 (winapp),我应该何时/在何处处置我的工作单元?

发布于 2024-09-20 00:19:00 字数 1955 浏览 5 评论 0原文

我有一个 Windows 应用程序,它创建一些线程来解析一些 txt 文件。没什么太疯狂的。

我正在使用 StructureMap 依赖注入来创建我的服务和存储库的任何实例。所以我的 Winform 有一个静态属性,它根据注册的内容返回实例。效果很好..除了我不确定什么时候应该处理我的工作单元?

我每个线程有一个工作单元。现在,线程并没有真正停止。他们继续滴答作响。当然,主要的 Forms 应用程序也是它自己的线程..并且直到您杀死它才停止。因此,我不确定何时应该处理 UnitOfWork (然后关闭上下文连接)。

传统上,我一直在进行 Web 应用程序编程(现在是 ASP.NET MVC),因此我可以在请求结束时进行处理……并且在同一请求中使用相同的 UnitOfWork。效果很好...但是在 winform 中没有结束请求:(

有什么想法吗?

这里有一些代码来解释我在做什么...

注册我的存储库类...

public class EntityFrameworkRepositoryRegistry : Registry
{
    public EntityFrameworkRepositoryRegistry(string connectionString)
    {
        For<IUnitOfWork>()
                .HybridHttpOrThreadLocalScoped()
                .Use<SqlServerUnitOfWork>()
                .Ctor<string>("connectionString")
                    .Is(connectionString)
                .Ctor<ILoggingService>("loggingService")
                    .Is(new NLogLoggingService(GetType().ToString()))
                .SetProperty(x => x.EntityContainerName = "Entities");

        EntityFrameworkProfiler.Initialize(); // Hi Ayende :) Love this :)

        Scan(x =>
                    {
                        x.TheCallingAssembly();

                        x.ExcludeNamespaceContainingType<FakeContext>();

                        x.WithDefaultConventions();
                    }
            );
    }
}

并在表单中使用存储库.. (是的,这应该是一个服务,但我还没有将其抽象出来......

private static IUserRepository GetUserRepository()
{
    return ObjectFactory.GetInstance<IUserRepository>();
}

private void LoadUserInformation()
{
    DisplayText("Reading in active users... ", false);
    _users = GetUserRepository().Find().WhereIsActive().ToList();
    DisplayText("done.", false, true);
    DisplayText("Found " + _users.Count + " active users.");
}

现在我可以在使用 call ToList() 之后调用 Dispose(); 但其他任何东西都不能使用该 UnitOfWork ?

有什么想法吗

I've got a windows application that creates some threads to parse some txt files. Nothing too crazy.

I'm using StructureMap Dependency Injection to create any instances of my Services and Repositories. So my Winform has a static property which returns the instance, based on what's been registered. Works great .. except I'm not sure when I should be disposing of my unit of work?

I've got a single UnitOfWork per thread. Now, the threads don't really stop. they keep on ticking over. Of course, the main Forms app is it's own thread, too .. and that doesn't stop until you kill it. So, i'm not sure when I should be disposing of the UnitOfWork (which then closes the context connection).

Traditionally, I've been doing web app programming (ASP.NET MVC now) so I can dispose at the end of the request ... and the same UnitOfWork was being used throughout that same request. That works nice ... But there is not end request, in a winform :(

Any ideas?

Here's some code to explain what I'm doing...

Registering my Repository classes...

public class EntityFrameworkRepositoryRegistry : Registry
{
    public EntityFrameworkRepositoryRegistry(string connectionString)
    {
        For<IUnitOfWork>()
                .HybridHttpOrThreadLocalScoped()
                .Use<SqlServerUnitOfWork>()
                .Ctor<string>("connectionString")
                    .Is(connectionString)
                .Ctor<ILoggingService>("loggingService")
                    .Is(new NLogLoggingService(GetType().ToString()))
                .SetProperty(x => x.EntityContainerName = "Entities");

        EntityFrameworkProfiler.Initialize(); // Hi Ayende :) Love this :)

        Scan(x =>
                    {
                        x.TheCallingAssembly();

                        x.ExcludeNamespaceContainingType<FakeContext>();

                        x.WithDefaultConventions();
                    }
            );
    }
}

and using the repository in the Form ... (yes, this should be a service, but i've not abstracted that out, just yet...

private static IUserRepository GetUserRepository()
{
    return ObjectFactory.GetInstance<IUserRepository>();
}

private void LoadUserInformation()
{
    DisplayText("Reading in active users... ", false);
    _users = GetUserRepository().Find().WhereIsActive().ToList();
    DisplayText("done.", false, true);
    DisplayText("Found " + _users.Count + " active users.");
}

.. now I can just call Dispose(); after I use call ToList() but then nothing else can use that UnitOfWork ???

Any ideas ?

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

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

发布评论

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

评论(1

拥醉 2024-09-27 00:19:04

我没有编写很多桌面应用程序,但我知道的最常见的模式是将工作单元的范围限制在屏幕上(例如,新的或编辑 CRUD 屏幕)。不过,您的应用程序看起来像是一个单一的表单,因此也许您可以接受在应用程序的生命周期中存在的单个工作单元。由于 DataContext 不保持与数据库的打开连接,因此这应该不是问题。

另一种选择是对每个用户操作使用一个工作单元(每个按钮单击都会获得自己的实例)。如果您决定走这条路,请确保您的工作单元注册为瞬态并自行管理生命周期。

I have not written many desktop apps, but the most common pattern I know of is to scope your unit of work to a screen (like a new or edit CRUD screen for example). It looks like your app is a single form though, so maybe you are fine with a single unit of work that lives for the lifetime of the application. Since the DataContext does not hold an open connection to the database, that should not be a problem.

The other option would be to use a unit of work per user action (every button click gets its own instance). If you decide to go that route, make sure your unit of work is registered as transient and manage the lifetime yourself.

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