代码之家  ›  专栏  ›  技术社区  ›  One Developer

如何在完成请求后立即处理Unity DI创建的对象?

  •  7
  • One Developer  · 技术社区  · 7 年前

    我想知道是否有更好的方法来处理这个问题。

    我已经为我们的项目建立了依赖注入的Unity。该项目本身是一个ASP。NET应用程序,该应用程序使用Web API。

    我安装了以下软件包。

    • 团结一致
    • 团结一致ASPNet。WebAPI

    我看不到在获取数据后立即关闭/处置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);
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  7
  •   Jasen    7 年前

    首先,您可能想在您的项目Unity中再添加一个Unity引导程序。AspNet。Mvc公司

    https://msdn.microsoft.com/en-us/library/dn507440(v=pandp.30).aspx

    在ASP中使用PerRequestLifetimeManager类。NET Web API应用程序,您还必须为ASP添加Unity bootstrapper。NET MVC NuGet包到您的项目中。

    团结一致Mvc和Unity。AspNet。WebApi将为DI注册控制器。

    UnityConfig。反恐精英

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<INinjaContext, NinjaContext>(new PerRequestLifetimeManager());
        container.RegisterType<INinjaRepository, NinjaRepository>(new PerRequestLifetimeManager());
    }
    

    UnityWebAPI激活器。反恐精英 取消对行的注释。。。

    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);
    
        ...
    }
    

    UnityMV激活器。反恐精英 取消对行的注释。。。

    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

    如果您正在使用 奥温 看见 Unity IoC does not inject dependency into Web API Controller