如何在完成请求后立即处理Unity DI创建的对象?
How to dispose the object created by Unity DI right after the completing the request?
我想知道是否有更好的方法来处理这个问题。
我已经为我们的项目设置了 Unity 依赖注入。该项目本身是一个使用 Web API.
的 ASP.NET 应用程序
我安装了以下软件包。
- 团结
- Unity.ASPNet.WebAPI
我看不到在获取数据后 close/dispose DBContext 的选项。
我的控制器
public class NinjasController : ApiController
{
public Ninja Get(int id)
{
INinjaRepository repository = UnityConfig.Container.Resolve(typeof(INinjaRepository), null) as INinjaRepository;
Ninja ninja = repository.GetNinjaById(id);
repository.CanBeDisposed = true;
repository = null;
UnityConfig.PerRequestLifetimeManager.Dispose();
return ninja;
}
}
UnityConfig
public static class UnityConfig
{
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
public static PerRequestLifetimeManager PerRequestLifetimeManager;
public static void RegisterTypes(IUnityContainer container)
{
PerRequestLifetimeManager = new PerRequestLifetimeManager();
container.RegisterType<INinjaRepository, NinjaRepository>(PerRequestLifetimeManager);
}
}
终身经理
public class PerRequestLifetimeManager : TransientLifetimeManager, IDisposable
{
private static List<IBaseRepository> list = new List<IBaseRepository>();
public override void SetValue(object newValue, ILifetimeContainer container = null)
{
base.SetValue(newValue, container);
IBaseRepository disposable = newValue as IBaseRepository;
if (disposable != null)
list.Add(disposable);
}
public void Dispose()
{
foreach (IBaseRepository item in list.FindAll(item => item.CanBeDisposed))
{
if (item != null)
{
try
{
item.Dispose();
}
catch (Exception)
{
// log exception and continue
}
}
}
list.RemoveAll(item => item.CanBeDisposed);
}
}
存储库
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
internal DbContext _context;
internal DbSet<TEntity> _dbSet;
public bool CanBeDisposed { get; set; }
public GenericRepository(DbContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
}
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
首先,您可能想在项目中再添加一个 Unity 引导程序 Unity.AspNet.Mvc
https://msdn.microsoft.com/en-us/library/dn507440(v=pandp.30).aspx
To use the PerRequestLifetimeManager class in an ASP.NET Web API application, you must also add the the Unity bootstrapper for ASP.NET MVC NuGet package to your project.
Unity.Mvc 和 Unity.AspNet.WebApi 将为您的控制器注册 DI。
UnityConfig.cs
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<INinjaContext, NinjaContext>(new PerRequestLifetimeManager());
container.RegisterType<INinjaRepository, NinjaRepository>(new PerRequestLifetimeManager());
}
UnityWebApiActivator.cs 取消注释行...
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use
// a new child container for each IHttpController resolution.
var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.Container);
...
}
UnityMvcActivator.cs 取消注释行...
public static void Start()
{
...
// TODO: Uncomment if you want to use PerRequestLifetimeManager
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
你的控制器就是
public class NinjasController : ApiController
{
private readonly INinjaRepository repository;
public NinjasController(INinjaRepository repository)
{
this.repository = repository;
}
public Ninja Get(int id)
{
var ninja = repository.GetNinjaById(id);
return ninja;
}
}
使用 PerRequestLifetimeManager Unity 将在请求完成后处理。
我这里有个例子https://github.com/jasenhk/MovieStar
如果您使用的是 OWIN,请参阅
我想知道是否有更好的方法来处理这个问题。
我已经为我们的项目设置了 Unity 依赖注入。该项目本身是一个使用 Web API.
的 ASP.NET 应用程序我安装了以下软件包。
- 团结
- Unity.ASPNet.WebAPI
我看不到在获取数据后 close/dispose DBContext 的选项。
我的控制器
public class NinjasController : ApiController
{
public Ninja Get(int id)
{
INinjaRepository repository = UnityConfig.Container.Resolve(typeof(INinjaRepository), null) as INinjaRepository;
Ninja ninja = repository.GetNinjaById(id);
repository.CanBeDisposed = true;
repository = null;
UnityConfig.PerRequestLifetimeManager.Dispose();
return ninja;
}
}
UnityConfig
public static class UnityConfig
{
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer Container => container.Value;
public static PerRequestLifetimeManager PerRequestLifetimeManager;
public static void RegisterTypes(IUnityContainer container)
{
PerRequestLifetimeManager = new PerRequestLifetimeManager();
container.RegisterType<INinjaRepository, NinjaRepository>(PerRequestLifetimeManager);
}
}
终身经理
public class PerRequestLifetimeManager : TransientLifetimeManager, IDisposable
{
private static List<IBaseRepository> list = new List<IBaseRepository>();
public override void SetValue(object newValue, ILifetimeContainer container = null)
{
base.SetValue(newValue, container);
IBaseRepository disposable = newValue as IBaseRepository;
if (disposable != null)
list.Add(disposable);
}
public void Dispose()
{
foreach (IBaseRepository item in list.FindAll(item => item.CanBeDisposed))
{
if (item != null)
{
try
{
item.Dispose();
}
catch (Exception)
{
// log exception and continue
}
}
}
list.RemoveAll(item => item.CanBeDisposed);
}
}
存储库
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
internal DbContext _context;
internal DbSet<TEntity> _dbSet;
public bool CanBeDisposed { get; set; }
public GenericRepository(DbContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
}
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
首先,您可能想在项目中再添加一个 Unity 引导程序 Unity.AspNet.Mvc
https://msdn.microsoft.com/en-us/library/dn507440(v=pandp.30).aspx
To use the PerRequestLifetimeManager class in an ASP.NET Web API application, you must also add the the Unity bootstrapper for ASP.NET MVC NuGet package to your project.
Unity.Mvc 和 Unity.AspNet.WebApi 将为您的控制器注册 DI。
UnityConfig.cs
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<INinjaContext, NinjaContext>(new PerRequestLifetimeManager());
container.RegisterType<INinjaRepository, NinjaRepository>(new PerRequestLifetimeManager());
}
UnityWebApiActivator.cs 取消注释行...
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use
// a new child container for each IHttpController resolution.
var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.Container);
...
}
UnityMvcActivator.cs 取消注释行...
public static void Start()
{
...
// TODO: Uncomment if you want to use PerRequestLifetimeManager
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
你的控制器就是
public class NinjasController : ApiController
{
private readonly INinjaRepository repository;
public NinjasController(INinjaRepository repository)
{
this.repository = repository;
}
public Ninja Get(int id)
{
var ninja = repository.GetNinjaById(id);
return ninja;
}
}
使用 PerRequestLifetimeManager Unity 将在请求完成后处理。
我这里有个例子https://github.com/jasenhk/MovieStar
如果您使用的是 OWIN,请参阅