2

Ich möchte wissen, ob es einen besseren Weg gibt, damit umzugehen.Wie wird das Objekt, das von Unity DI erstellt wurde, direkt nach dem Ausfüllen der Anfrage gelöscht?

Ich habe Unity für die Abhängigkeitsinjektion für unser Projekt eingerichtet. Das Projekt selbst ist eine ASP.NET-Anwendung, die Web-API verwendet.

Ich habe die folgenden Pakete installiert.

  • Unity
  • Unity.ASPNet.WebAPI

Ich sehe keine Option/schließen Sie die DbContext entsorgen direkt nach dem die Daten abgerufen werden.

Mein Controller

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

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

Repository

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

sehen Wenn richtig konfiguriert ist, würde der DI-Container für die Entsorgung behandeln für Sie auf die Lebensdauer der Regel basiert. Unity fügt die Abhängigkeit (Ihr Repository) über den Konstruktor des Controllers ein - Sie müssen ihn nicht direkt in Ihrer Aktion aufrufen. Sie müssen DbContext mit Unity registrieren, damit es mit der angegebenen Lebensdauer verwaltet werden kann. – Jasen

+0

Ich würde - öffentliche NinjasController (INinjaRepository Repository) und registriert sowohl das Repository und DBcontext - container.RegisterType (); & container.RegisterType (); @Jasen, Dispose-Methode wurde nie aufgerufen, wenn der jeweilige LifetimeManager verwendet wurde. Können Sie mir bitte mit einer Probe helfen, wenn Sie könnten. –

Antwort

3

Zuerst möchten Sie vielleicht Ihr Projekt Unity.AspNet.Mvc

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

Zur Verwendung der PerRequestLifetimeManager Klasse in einer ASP.NET Web-API-Anwendung eine weitere Einheit Bootstrap-Programm hinzuzufügen, können Sie auch die müssen hinzufügen Unity-Bootstrapper für das ASP.NET MVC NuGet-Paket für Ihr Projekt.

Unity.Mvc und Unity.AspNet.WebApi registrieren Ihre Controller für DI.

UnityConfig.cs

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

UnityWebApiActivator.cs Kommentar- der Linie ...

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 Kommentar- der Linie ...

public static void Start() 
{ 
    ... 

    // TODO: Uncomment if you want to use PerRequestLifetimeManager 
    Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule)); 
} 

Ihr Controller ist einfach

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

Mit PerRequestLifetimeManager Unity die Entsorgung stattfinden wird, nachdem die Anforderung abgeschlossen ist.

Ich habe hier ein Beispiel https://github.com/jasenhk/MovieStar

Wenn Sie mit OWINUnity IoC does not inject dependency into Web API Controller

Verwandte Themen