I have a code where controller calls service and service use Unit Of Work to handle DB. I have used Unity as dependency injection. I need to dispose unity(dbContext) automatically after request scope ends. I am not getting reference to PerRequestLifetimeManager in UnityCofig.cs. Any pointers?
Try creating new derived type of lifetime manager
public class PerHttpRequestLifetime : LifetimeManager
{
// This is very important part and the reason why I believe mentioned
// PerCallContext implementation is wrong.
private readonly Guid _key = Guid.NewGuid();
public override object GetValue()
{
return HttpContext.Current.Items[_key];
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[_key] = newValue;
}
public override void RemoveValue()
{
var obj = GetValue();
HttpContext.Current.Items.Remove(obj);
}
}
Source:
MVC, EF - DataContext singleton instance Per-Web-Request in Unity
Related
We are in the middle of attempting a drop-in replacement of Autofac for Ninject in our windows service (before potentially making more enhancement to take care of Autofac features), but are running into a memory issue.
Here's a contrived example that doesn't reproduce our issue, but demonstrates the current layout of the app:
class Program
{
static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
var ms = new MemoryStream(new byte[10000000]);
var ms2 = new MemoryStream(new byte[10000000]);
builder.RegisterType<BaseRepo>()
.WithParameter("ms", ms)
.As<IBaseRepo>();
builder.RegisterType<DerivedRepo>()
.WithParameter("ms", ms2)
.As<IDerivedRepo>();
builder.RegisterType<BaseFactory>().As<IBaseFactory>();
builder.RegisterType<Derived>().AsSelf();
builder.RegisterType<Derived>().Keyed<Base>(BaseEnum.Derived).As<Base>();
var container = builder.Build();
var factory = container.Resolve<IBaseFactory>();
while (true)
{
var instance = factory.Create(BaseEnum.Derived);
instance.DoSomething();
instance.Dispose();
Thread.Sleep(5000);
}
}
}
public interface IDerivedRepo : IDisposable {}
public class DerivedRepo : IDerivedRepo
{
private readonly MemoryStream _ms;
public DerivedRepo(MemoryStream ms)
{
_ms = ms;
}
public void Dispose()
{
_ms.Dispose();
}
}
public interface IBaseRepo : IDisposable {}
public class BaseRepo : IBaseRepo
{
private readonly MemoryStream _ms;
public BaseRepo(MemoryStream ms)
{
_ms = ms;
}
public void Dispose()
{
_ms.Dispose();
}
}
public enum BaseEnum
{
Derived = 1
}
public interface IBaseFactory
{
Base Create(BaseEnum baseEnum);
}
public class BaseFactory : IBaseFactory
{
private readonly IComponentContext _componentContext;
public BaseFactory(IComponentContext componentContext)
{
_componentContext = componentContext;
}
public Base Create(BaseEnum baseEnum)
{
return _componentContext.ResolveOptionalKeyed<Base>(baseEnum);
}
}
public interface IDisposableThing : IDisposable
{
void DoSomething();
}
public abstract class Base : IDisposableThing
{
protected readonly IBaseRepo BaseRepo;
protected Base(IBaseRepo baseRepo)
{
BaseRepo = baseRepo;
}
public void Dispose()
{
Console.WriteLine("Disposing base");
BaseRepo.Dispose();
}
public abstract void DisposeChildren();
public void DoSomething()
{
Console.WriteLine("Doing something");
}
}
public class Derived : Base
{
private readonly IDerivedRepo _derivedRepo;
public Derived(IBaseRepo baseRepo, IDerivedRepo derivedRepo) : base(baseRepo)
{
_derivedRepo = derivedRepo;
}
public override void DisposeChildren()
{
Console.WriteLine("Disposing derived");
_derivedRepo.Dispose();
}
}
Basically, we--at regular intervals--use a factory to instantiate an instance of an abstract class based on an enum value, do some work with that instance, then dispose of it. The problem is that those instances are not getting cleaned up by the garbage collector and the memory usage of the app increases steadily, with DebugDiag2 reporting that it is holding onto instances of the equivalent of our MemoryStream members in our repos (in our real app, these are wrappers over Entity Framework DBContext), with no other references to our code reported in its analysis so I have nothing else to go on.
I know there probably isn't enough here to give a definitive answer, what I'm more looking for is suggestions on where we are obviously doing something wrong (the whole team is new to Autofac and I know we are using the service locator anti-pattern, but I assume that isn't causing the problems we are seeing).
The behavior you experience is normal as Autofac keeps track, within a lifetime scope, of objects it resolves. These will be disposed when the associated lifetime scope is itself disposed. In your case, you only have one lifetime scope, the one created when you build the container from the builder.
I suggest that you have a good read of this documentation page which explains more in detail how lifetime scopes work.
A starting point would be to create an inner lifetime scope every time you start new work within the regular interval. It could look something like this:
var container = builder.Build();
while (true)
{
// Create an inner lifetime scope that will keep track of every
// object it creates
using (var lifetimeScope = container.BeginLifetimeScope())
{
// resolve objects from `lifetimeScope`
// do work with them
}
// At the end of the using directive, lifetimeScope will be disposed
// and will dispose with it any objects it kept track of
Thread.Sleep(5000);
}
Plain and simple as the title suggests, is this a possible thing using Autofac dependency injection? I have been trying and searching everywhere.. I'm losing hope here.
My class has to be singleton - that can't change. I want it to take a factory of unit of works - for database transactions.
Please help me figure this one out, I'm deseperate.
Tried Func<> and registering my unit of work in every possible way (all sorts of lifetimes, externally owned or not) but failed because the DbContext within the unit of work is disposed and not created again after the first request
Edit:
Added code that will hopefully help understanding my problem:
public class SingletonDataService : IDataService
{
private _uowFactory;
public SingletonDataService(Func<IEFUnitOfWork> uowFactory)
{
_uowFactory = uowFactory
}
public List<Folder> GetAllFolders ()
{
using (uow = uowFactory())
{
return uow.FoldersRepository.GetAll();
}
}
}
public MyDbContext : DbContext
{
public DbSet<Folder> Folders {get; set;}
public DbSet<Letter> Letters {get; set;}
public MyDbContext() : base("myContext...")
}
public EFUnitOfWork : IEFUnitOfWork, IDisposable
{
public IRepository<Folder> FoldersRepository;
public IRepository<Letter> LettersRepository;
private DbContext _context;
public EFUnitOfWork(IRepository<Folder> folders, IRepository<Letter> letters, DbContext context)
{
_folders = folders;
_letters = letters;
_context = context;
}
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
_context.Dispose();
}
disposed = true;
}
}
}
public Repository<T> : IRepository<T> where T: BaseEntity
{
private DbContext _context;
private DbSet<T> _set
public Repository(DbContext context)
{
_context = context;
_set = _context.Set<T>();
}
}
public LettersController : ApiController
{
private IDataService _dataService;
public LettersController(IDataService dataService)
{
_dataService = dataService;
}
[HttpGet]
public IHttpActionResult GetAllLetters()
{
return Ok(_dataService.GetAllLetters());
}
}
// Must be singleton
builder.Register<SingletonDataService>().As(IDataService).SingleInstance();
builder.RegisterGeneric(typeof(Repository<>))
.As(typeof(IRepository<>))
.InstancePerLifetimeScope();
builder.Register<EFUnitOfWork>().As(IEFUnitOfWork).InstancePerLifetimeScope();
builder.Register<DbContext>().As(AppDbContext).InstancePerLifetimeScope();
In the first request everything works fine, in the second third and so on I get this exception :
system.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I clearly see it happens because the context in my repository is now null, but I don't how to to change that with the DI.
What I want to achieve is so easy without DI :
How can I achieve the following with Autofac??
public class UowFactory
{
public UowFactory()
{
}
public IEFUnitOfWork Create()
{
var context = new AppDbContext()
var uow = new EFUnitOfWork(new Repository<Folder>(context), new Repository<Letter>(context), context);
return uow;
}
}
Issue
You are registering the critial components with InstancePerLifetimeScope()
When the autofac container is built it also creates a root ILifetimeScope which lives until IContainer.Dispose() is called. Now unless you create nested ILifetimeScope somewhere in the chain to the SingletonDataService, the ILifetimeScope which is used your components is the root ILifetimeScope and InstancePerLifetimeScope() effectly becomes equivalent to SingleInstance().
Solution
One of the possible solutions is to create an ILifetimeScope per IEFUnitOfWork and its children. Autofac facilitates this by providing the Owned<T> type. We can use it in conjunction with a Func<> factory (also see documentation):
public class SingletonDataService : IDataService
{
private Func<Owned<IEFUnitOfWork>> _uowFactory;
public SingletonDataService(Func<Owned<IEFUnitOfWork>> uowFactory)
{
_uowFactory = uowFactory
}
public List<Folder> GetAllFolders ()
{
using (var uow = _uowFactory())
{
return uow.Value.FoldersRepository.GetAll();
}
}
}
This should play nicely with the following registrations:
// Must be singleton
builder.Register<SingletonDataService>().As(IDataService).SingleInstance();
builder.RegisterGeneric(typeof(Repository<>))
.As(typeof(IRepository<>))
.InstancePerLifetimeScope();
builder.Register<EFUnitOfWork>().As(IEFUnitOfWork).InstancePerLifetimeScope();
builder.Register<DbContext>().As(AppDbContext).InstancePerLifetimeScope();
However, note, that DbContext being bound with InstancePerLifetimeScope basically makes the manual disposal in EFUnitOfWork redundant.
Sidenote on proper Disposal
Since IDisposable types should support graceful multi-disposal , one should be able to simplify EFUnitOfWork.Dispose() to
public void Dispose()
{
_context.Dispose();
}
Also note, that i left out the call GC.SuppressFinalize(this);. This call is only relevant in case the class implements a custom finalizer (~EFUnitOfWork method) - or a deriving class could do so, otherwise the object is not put on the finalizer queue anyway.
Your problem is that you have a singleton (SingletonDataService) depend on a service that has a shorter lifetime (EFUnitOfWork). When the SingletonDataService instance is created by autofac, it gets an instance of EFUnitOfWork, but this instance will always stay the same (its actual lifetime will be longer than you expect) and thus gets disposed and used again, giving errors.
You have two possible solutions:
One is to create a UowFactory class like the one you defined at the bottom (but with dependencies on IRepository<Folder>, IRepository<Letter>, DbContext), register that as anything (for example singleton, but it won't matter) and make the SingletonDataService depend on it. This will likely not be a viable solution to you though, since it will also extend the lifetime of the IRepository<Folder>, IRepository<Letter>, DbContext instances and create problems there.
The proper solution is to remove the reason why you would want the SingletonDataService to be a singleton, probably some cache. And move it to a new service (CacheService?) on which the SingletonDataService depends and make that new service a singleton.
I want to implement a disposing transient lifetime manager for Unity version 3.5. The problem is that I don't know how to access the LifetimeManager in the PostTearDown,etc. steps of the BuilderStrategy class. context.Lifetime works fine in Unity 2.
Basically I have the following:
Container = new UnityContainer();
Container.AddNewExtension<DisposableStrategyExtension>();
Container.RegisterType<ITest, Test>(new DisposingTransientLifetimeManager());
public class DisposingLifetimeStrategy : BuilderStrategy
{
public override void PreBuildUp(IBuilderContext context)
{
base.PreBuildUp(context);
// context.Lifetime.Count == 0 here and in all other methods.
// In version 2 of unity this is set.
}
// implement rest of methods, but context.Lifetime.Count is 0 in all of them too.
public class DisposingTransientLifetimeManager : LifetimeManager
// implement abstract methods minimally
You can get the lifetime manager from the policy list:
public class DisposingLifetimeStrategy : BuilderStrategy
{
public override void PreBuildUp(IBuilderContext context)
{
ILifetimePolicy lifeTime = context.Policies.Get<ILifetimePolicy>(context.BuildKey);
base.PreBuildUp(context);
}
public override void PreTearDown(IBuilderContext context)
{
// Assumes registration name is null
var buildKey = new NamedTypeBuildKey(context.Existing.GetType());
ILifetimePolicy lifeTime = context.Policies.Get<ILifetimePolicy>(buildKey);
base.PreTearDown(context);
}
}
If you are calling IUnityContainer.Teardown(obj) then the PreTearDown and PostTearDown methods will not know the name of the resolved object. That may not matter as long as a default (null) registration exists (since I assume you just want to cast the object to an IDisposable and then Dispose the object).
Using Castle Windsor, I'd like to create a class that records an integer. But I'd like to decorate it several times with other classes. I can see how this works if all concretes involved have dependencies that can be resolved, but that's not the case here. Consider this code:
public interface IRecorder
{
void Add(int value);
}
public class NotifyingRecorder : IRecorder
{
readonly IRecorder decoratedRecorder;
public NotifyingRecorder(IRecorder decoratedRecorder)
{
this.decoratedRecorder = decoratedRecorder;
}
public void Add(int value)
{
decoratedRecorder.Add(value);
System.Console.WriteLine("Added " + value);
}
}
public class ModelUpdatingRecorder : IRecorder
{
int seed;
public ModelUpdatingRecorder(int seed)
{
this.seed = seed;
}
public void Add(int value)
{
seed += value;
}
}
And registered with:
container.Register(Component.For<IRecorder>().ImplementedBy<NotifyingRecorder>());
container.Register(Component.For<IRecorder>().ImplementedBy<ModelUpdatingRecorder>());
Resolving an IRecorder will never work here, since ModelUpdatingRecorder has a non-optional dependency. I cannot use a static dependency since seed is not known at compile-time.
Is there a way to specify the seed parameter at runtime and have the decoration still work?
This code sample is a simplification of my scenario, but the idea is the same. I have decorators, and the lowest one relies on a specific value/instance to be provided to it.
I've found a solution that I believe is the way this should be done. Down in the innards of Windsor the DefaultDependencyResolver has a method it uses to resolve sub-dependencies (such as a decorated instance of IRecorder above) called RebuildContextForParameter. It calls this to create a new context to use when resolving the dependency (i.e. the parameter to the constructor). The method is:
/// <summary>This method rebuild the context for the parameter type. Naive implementation.</summary>
protected virtual CreationContext RebuildContextForParameter(CreationContext current, Type parameterType)
{
if (parameterType.ContainsGenericParameters)
{
return current;
}
return new CreationContext(parameterType, current, false);
}
The false parameter in CreationContext constructor is propagateInlineDependencies, which when true will copy over the current context's AdditionalArguments, thereby passing down the parameters to the sub-dependencies.
To flip this false to true, create a new class that derives from DefaultDependencyResolver:
public class DefaultDependencyResolverInheritContext : DefaultDependencyResolver
{
protected override CreationContext RebuildContextForParameter(CreationContext current, Type parameterType)
{
if (parameterType.ContainsGenericParameters)
{
return current;
}
return new CreationContext(parameterType, current, true);
}
}
Then use that when creating the Windsor container:
var kernel = new DefaultKernel(
new DefaultDependencyResolverInheritContext(),
new NotSupportedProxyFactory());
var container = new WindsorContainer(kernel, new DefaultComponentInstaller());
The NotSupportedProxyFactory and DefaultComponentInstaller are the defaults when using the parameter-less constructors for DefaultKernel and WindsorContainer.
When done, the code above will work when a factory is used to create an IRecorder, i.e.:
// during type registration/bootstrapping
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IRecorder>().ImplementedBy<NotifyingRecorder>());
container.Register(Component.For<IRecorder>().ImplementedBy<ModelUpdatingRecorder>());
container.Register(Component.For<IRecorderFactory>().AsFactory());
Where IRecorderFactory is:
public interface IRecorderFactory
{
IRecorder Create(int seed);
}
Then this will work as expected:
IRecorderFactory recorderFactory = container.Resolve<IRecorderFactory>();
IRecorder recorder = recorderFactory.Create(20);
recorder.Add(6);
Hopefully that helps others!
You could wrap the seed in an interface (ISeedHolder ?) and register it with a singleton lifestyle. Then use the interface in your ModelUpdatingRecorder instead of the raw int. Unless your seeds may need to be parallelized it should allow you to set the seed and resolve it when constructing the ModelUpdatingRecorder
public interface ISeedHolder
{
int Seed {get;set;}
}
public class ModelUpdatingRecorder : IRecorder
{
int seed;
public ModelUpdatingRecorder(ISeedHolder seedHolder)
{
this.seed = seedHolder.Seed;
}
Would this solution achieve what you need?
Long story short, I'm trying to use ELMAH with MVC 2 and Ninject, and I need to use parameterless constructors. I created an initial post about it here: Using a parameterless controller constructor with Ninject?
I was advised to use property injection instead of constructor injection. So I moved from this:
public class DepartmentsController : Controller
{
private IDepartmentsRepository departmentsRepository;
public DepartmentsController(IDepartmentsRepository departmentsRepository)
{
this.departmentsRepository = departmentsRepository;
}
...
}
to this:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
...
}
But in my other controller functions, whether I try to access DepartmentsRepository or _departmentsRepository, I get an object reference not set to an instance of an object error when I try to access it.
Is there something else I need to do here?
I had a similar problem. Have a look at my questions: Using Ninject with Membership.Provider.
Basically when you initialise DepartmentsController you need to injectthis (i.e. your departments controller into your Ninject kernal. So its something like:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
public DepartmentsController()
{
NinjectHelper.Kernel.Inject(this);
}
}
Where NinjectHelper in this case gets the current Ninject Kernel.
Try something like this:
Global.asax.cs
protected void Application_Start()
{
DependencyResolver.SetResolver(
new MyDependencyResolver(
new StandardKernel(
new MyModule())));
//...
}
MyDependencyResolver.cs
public class MyDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public MyDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}
MyModule.cs
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IDepartmentsRepository>().To<DepartmentsRepository>();
}
}
There could be 2 reasons for object reference not set exception.
1) Ninject does not know how to Bind IDepartmentsRepository to a concrete implementation of DepartmentsRepository ( I doubt that is the case though )
2) If you are trying to access DepartmentsRepository property in your controller's constructor, it will throw the exception (since Ninject is only able to inject Property Dependencies after the object is constructed).
Hope that helps.
As Daniel T. in the above comment posted, you should check out Ninject.Web.Mvc. If you use the NinjectHttpApplication in that project, it will autowire everything for you, so that when the NinjectControllerFactory constructs a new controller, it will call Inject() for you to fill the property injections.
An observation for anyone arriving here having problems "Using property injection instead of constructor injection" with Ninject even if not specifically with MVC Controllers.
Ninject will only identify the [Inject] attribute on a property and perform the property injection on classes that are being brought to life as part of a Ninject chain of DI.
If you are creating the object like this
var myObj = new MyObj();
Ninject doesn't know about the class instantiation and so won't know to perform any injection.
In the MVC world you can use
var emailer = DependencyResolver.Current.GetService<IEmailer>();