完成请求后,如何处置由Unity DI创建的对象? [英] How to dispose the object created by Unity DI right after the completing the request?

查看:87
本文介绍了完成请求后,如何处置由Unity DI创建的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to know if there is a better to way to handle this.

我已经为我们的项目设置了Unity以进行依赖项注入。该项目本身是一个使用Web API的ASP.NET应用程序。

I've set up Unity for dependency injection for our project. The project itself is an ASP.NET application that uses Web API.

我安装了以下软件包。


  • Unity

  • Unity.ASPNet.WebAPI

我的控制器

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

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

Lifetime Manager

Lifetime Manager

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

First you might want to add one more Unity bootstrapper to your project Unity.AspNet.Mvc

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


要在ASP.NET Web API应用程序中使用PerRequestLifetimeManager类,还必须为ASP.NET MVC NuGet添加Unity引导程序。

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注册您的控制器。

Unity.Mvc and Unity.AspNet.WebApi will register your controllers for 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将在请求后处理完成。

With PerRequestLifetimeManager Unity will take care of disposal after the request is complete.

我在这里有一个示例 https:// github.com/jasenhk/MovieStar

如果您使用的是 OWIN ,请参见 Unity IoC不会将依赖项注入Web API控制器

If you are using OWIN see Unity IoC does not inject dependency into Web API Controller

这篇关于完成请求后,如何处置由Unity DI创建的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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