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