我想知道是否有更好的方法来处理这个问题。
我为我们的项目设置了Unity for dependency injection。项目本身是一个使用Web API的ASP.NET应用程序。
我安装了以下软件包。
我看不到在获取数据后立即关闭/处理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.AspNet.Mvc中再添加一个Unity引导程序
https://msdn.microsoft.com/en-us/library/dn507440(v=pandp.30).aspx
要在ASP.NET Web API应用程序中使用PerRequestLifetimeManager类,还必须将ASP.NET MVC NuGet包的Unity引导程序添加到项目中。
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 IoC does not inject dependency into Web API Controller