NamedScopes Ninject绑定和异步(线程) [英] NamedScopes Ninject bindings and async (threading)

查看:203
本文介绍了NamedScopes Ninject绑定和异步(线程)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目是由服务和存储库结构(所有存储库共享数据库上下文)。在我的服务层中的一个,我有写使用存储库数据库中的异步方法。 web请求将完成和处置的上下文之前该方法可以得到使用它。我试图了解 NamedScopes 的在本回答。我似乎仍不能明白如何实现它。我会告诉我的项目是如何构成的,希望有人能帮助我在代码级别。



绑定



 私有静态无效RegisterServices(的iKernel内核)
{
//的DbContext
kernel.Bind< EntityDatabaseContext>()。 ToMethod(上下文=>新建EntityDatabaseContext())。InRequestScope();

//工作
kernel.Bind&所述的单元; IUnitOfWork方式>()到<的UnitOfWork方式>()InRequestScope();

//库
kernel.Bind< IRepository<帐户>>()为<库<帐户>>()InRequestScope();

//服务
kernel.Bind&所述; IAuthenticationService>()至<的AuthenticationService方式>()InRequestScope();
}



的AuthenticationService使用构造函数注入

$ {}
$ b

 公开的AuthenticationService(;帐户> accountRepository的UnitOfWork的UnitOfWork,IRepository<) > 

我的AuthenticationService内的方法

  //这是一个后台进程
公共任务SomeMethodAsync(字符串文本)
{
//旋转它关到一个新的任务,
返回Task.Factory.StartNew(()=>的someMethod(文本));
}



的someMethod 利用的 accountRepository 。如果需要了信息请告诉我。请帮我穿线问题,如果NamedScopes是解决方案,我怎么实现它在我的情况?



基本上,正在执行的后台进程,它是使用正由ninject处置由于请求范围的上下文


解决方案

您应该知道,在运行的后台线程可以使你很多问题。 IIS可以决定回收随时应用程序池,将立即终止您的线程(或它不会在某些情况下执行的话)留下不一致的状态您的应用程序。



HTTP:/ /haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx



运行asyncronous操作的最简单和最容易出错京顺路是实现一个窗口服务,并委托这些异步操作的windows服务例如:使用MSMQ。



如果您还想去硬盘的方式,然后阅读 HostingEnvironment.RegisterObject IRegisteredObject 来防止这些不一致的情况。



Ninject部分是很容易的。只是创造一些就业处理器类如 MyJobProcessor 采取一切需要的依赖来执行任务。它应该落实 INotifyWhenDisposed 。这样做最简单的方法是从 DisposeNotifyingObject 派生。

 公开类MyJobProcessor:DisposeNotifyingObject,IRegisteredObject 
{
公共无效执行(){...}
公共无效停止(BOOL立即){...}
}

注入该处理器的控制器,让任务启动它,处理它时,它已经完成它的工作。

  Task.Factory.StartNew(()=> 
{

{
processor.Execute();
}
终于
{
processor.Dispose);
}
});



指定这是其依赖的范围。

 绑定< MyJobProcessor>()ToSelf()命名(MyJobProcessor)DefinesNamedScope(MyJobProcessorScope)。; 
绑定&所述; IUnitOfWork方式>()到<的UnitOfWork方式>()WhenAnyAnchestorNamed(MyJobProcessor)InNamedScope(MyJobProcessorScope);


My project is structured by services and repositories (all repositories share the db context). In one of my service layers, I have an asynchronous method that writes to the database using a repository. The web request will finish and dispose of the context before this method can get to use it. I tried to understand NamedScopes as stated in this answer. I still can't seem to understand how to implement it. I'll show how my project is structured and hope someone can help me at the code level.

Bindings

    private static void RegisterServices(IKernel kernel)
    {
        //dbcontext
        kernel.Bind<EntityDatabaseContext>().ToMethod(context => new EntityDatabaseContext()).InRequestScope();

        //unit of work
        kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();

        //repositories
        kernel.Bind<IRepository<Account>>().To<Repository<Account>>().InRequestScope();

        //services
        kernel.Bind<IAuthenticationService>().To<AuthenticationService>().InRequestScope();
    }

AuthenticationService uses constructor injection

public AuthenticationService(UnitOfWork unitOfWork, IRepository<Account> accountRepository){}

A method inside my AuthenticationService

    //this is a background process
    public Task SomeMethodAsync(string text)
    {
        //spin it off into a new task
        return Task.Factory.StartNew(() => SomeMethod(text));
    }

SomeMethod makes use of accountRepository. Please tell me if anymore information is needed. Please help me with the threading issue, if NamedScopes is the solution, how do I implement it in my case?

Basically, a background process is being executed and it is using a context that is being disposed of by ninject due to the request scope.

解决方案

You should be aware that running background threads can cause you many problems. IIS can decide to recycle the app pool at any time which will terminate your thread immediately (or it doesn't execute in some cases at all) leaving your application in an inconsistent state.

http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

The easiest and least error prone wayto run asyncronous operations is to implement a windows service and delegate those async operations to the windows service e.g. using MSMQ.

If you still want to go the hard way then read about HostingEnvironment.RegisterObject and IRegisteredObject to prevent these inconsistent situations.

The Ninject part is quite easy. Just create some job processor class e.g. MyJobProcessor taking all required dependencies to execute the task. It should implement INotifyWhenDisposed. The easiest way to do so is to derive from DisposeNotifyingObject.

public class MyJobProcessor : DisposeNotifyingObject, IRegisteredObject
{
    public void Execute() { ... }
    public void Stop(bool immediate) { ... }
}

Inject this processor to the controller and let the Task start it and dispose it when it has finished its work.

Task.Factory.StartNew(() => 
    { 
        try 
        { 
            processor.Execute(); 
        } 
        finally 
        { 
            processor.Dispose); 
        }
    });

Specify that it is the scope for its dependencies.

Bind<MyJobProcessor>().ToSelf().Named("MyJobProcessor").DefinesNamedScope("MyJobProcessorScope");
Bind<IUnitOfWork>().To<UnitOfWork>().WhenAnyAnchestorNamed("MyJobProcessor").InNamedScope("MyJobProcessorScope");

这篇关于NamedScopes Ninject绑定和异步(线程)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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