gpt4 book ai didi

c# - 使用 Unity MVC Bootstrap 拆卸注入(inject)类型

转载 作者:行者123 更新时间:2023-11-30 16:11:56 24 4
gpt4 key购买 nike

我正在使用 ASP.NET MVC WebApi 2 并使用 Unity 3 将具体类型注入(inject) Controller ,并且这个Unity MVC bootstrapper .

这里的问题是注册类型初始化一个 Entity Framework 6 DbContext对于每一个决心:

public sealed class EntityFrameworkUnitOfWork : IUnitOfWork
{
internal DbContext Context { get; private set; }

public EntityFrameworkUnitOfWork()
{
Context = new SomeContext();
}

public void Commit()
{
Context.SaveChanges();
}

public void Dispose(bool disposing)
{
if (disposing)
{
if (Context != null)
{
Context.Dispose();
Context = null;
}
}
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

例如,EntityFrameworkUnitOfWork将构造函数注入(inject)到这样的 Controller 中:

public class UserController : ApiController
{
public UsersController(IUserRepository userRepository, IUnitOfWork unitOfWork)
{
// unitOfWork is a EntityFrameworkUnitOfWork
}

// ...
}

当相关的MVC Controller 配置时,我需要Dispose()在上面调用的方法 EntityFrameworkUnitOfWork类型,这反过来将处理底层 DbContext .

向 Unity 注册此类型:

Container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(
new DisposingTransientLifetimeManager()
);

我正在使用 DisposingTransientLifetimeManager生命周期管理器,如 this article 中所建议,认为它会自动处理我的 IDisposable类型。看来还是得打电话Container.Teardown(someInstance) .这对我来说是不可能的,因为 MVC Bootstrapper 正在处理所有 DI 解析。

我在哪里以及如何执行这些初始化类型的拆卸?

最好在相关的 MVC Controller 销毁时执行此拆卸,但也许这也可以发生在 HTTP 请求结束时?

编辑:

注入(inject)的 IDisposables 不一定能从 Controller 访问。例如,我还可以注入(inject) IUserService进入一个 Controller ,它本身(IUserService 类)被注入(inject)了一个 IUserRepository和一个 IUnitOfWork .我可以从 IUserService 链接 Dispose 方法处理它们,但这需要更改数百个 Controller 和服务。理想情况下我应该可以调用 container.Dispose()某个地方让 Unity 处理所有注入(inject)的一次性用品。

编辑 2:

RaraituL 让我想起了其他事情。 IUnitOfwork不执行IDisposable , 只有 EntityFrameworkUnitOfWork做。这实质上意味着 MVC Controller 将无法调用 dispose 方法,因为它只知道 IUnitOfWork。 .这是 Unity 应该这样做的另一个原因 - 它创建了 IDisposables,所以它也应该处理它们。

最佳答案

听起来您想要一个 PerRequestTransientLifetimeManager。那将是您必须构建的东西。这并不难,因为您使用的是 Unity 3,大部分工作已经为您完成。

public class PerRequestTransientLifetimeManager : ILifetimePolicy
{
public object GetValue()
{
// will always create a new object (Transient)
return null;
}

public void SetValue(object newValue)
{
// No point in saving to http context if not disposable
if (newValue is IDisposable)
{
var perRequestLifetimeManager = new PerRequestLifetimeManager();
perRequestLifetimeManager.SetValue(newValue);
}
}


public void RemoveValue()
{
// can't remove since transient didn't keep a reference
}
}

你需要 Unity.Mvc如果缺少 PerRequestLifetimeManager 类,则为 nuget 包。您还需要使用 Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule 注册 UnityPerRequestHttpModule

我应该从 MS site 指出

Although the PerRequestLifetimeManager lifetime manager works correctly and can help in working with stateful or thread-unsafe dependencies within the scope of an HTTP request, it is generally not a good idea to use it when it can be avoided, as it can often lead to bad practices or hard to find bugs in the end-user's application code when used incorrectly. It is recommended that the dependencies you register are stateless and if there is a need to share common state between several objects during the lifetime of an HTTP request, then you can have a stateless service that explicitly stores and retrieves this state using the Items collection of the Current object.

关于c# - 使用 Unity MVC Bootstrap 拆卸注入(inject)类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23674842/

24 4 0
文章推荐: c# - 如何按字母顺序按键对 SortedDictionary 集合进行排序
文章推荐: javascript - 在 jQuery 点击功能上显示特定数量的
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com