I have an ASP.NET MVC app that creates a Linq2SQL datacontext on a per-web-request basis using Castler Windsor IoC.
For some reason that I do not fully understand, every time a new datacontext is created (on every web request) about 8k of memory is taken up and not released - which inevitably causes an OutOfMemory exception.
If I force garbage collection the memory is released OK.
My datacontext class is very simple:
public class DataContextAccessor : IDataContextAccessor
{
private readonly DataContext dataContext;
public DataContextAccessor(string connectionString)
{
dataContext = new DataContext(connectionString);
}
public DataContext DataContext { get { return dataContext; } }
}
The Windsor IoC webconfig to instantiate this looks like so:
<component id="DataContextAccessor"
service="DomainModel.Repositories.IDataContextAccessor, DomainModel"
type="DomainModel.Repositories.DataContextAccessor, DomainModel"
lifestyle="PerWebRequest">
<parameters>
<connectionString>
...
</connectionString>
</parameters>
</component>
Does anyone know what the problem is, and how to fix it?
L2S DataContext implements IDisposable. Your interface also has to implement it, and call DataContext.Dispose(), so that Windsor knows that there're resources to be disposed.
By the way beware of Windsor/IDisposable problems:
http://www.jeremyskinner.co.uk/2008/05/03/aspnet-mvc-controllers-windsor-and-idisposable/
http://www.nablasoft.com/Alkampfer/?p=105
No your DataContextAccessor does not need to implement IDisposable. Windsor is smart enough to handle the case without having to do any modifications to your classes.
However since as noted in the other answers DataContext does implement it, and Windsor sees it and it registers it for cleanup (to call the Dispose method on it).
What you need to do is to call container.Release and pass your root service (which probably would be DataContextAccessor in your case). Windsor will then release it and all its dependencies (it will also call Dispose on DataContext) and the memory will be freed.
If you're using ASP.NET MVC consider using MVCContrib project which has Windsor integration that handles releasing of components for you.
From what I can tell, queen3 is correct, your DataContextAccessor class needs to implement IDisposable and call datacontext.Dispose() from its .Dispose() method. (Disclaimer: I haven't worked with Castle Windsor.)
Alternatively, what I would do is turn your DataContextAccessor into a DataContextFactory, which only creates the DataContext when you call a method (e.g. GetContext()). Then you can do this:
using(DataContext context = myDataContextFactory.GetContext()) {
// Do whatever you want with the context
}
// Context is disposed here
You might also want to take a look at this previous question: How do you reconcile IDisposable and IoC?
I think #Krzysztof Koźmic is right... you should release whatever you get from Windsor.
Windsor is pretty alien to anyone used to IDisposable. The reason for this apparent disparity is down to the management of the component's lifecycle. If you take a component from Windsor that is IDisposable, you don't know if that instance is configured as transient or a singleton (and of course this could change as your app evolves).
If you dispose a component and it later turns out to be a singleton, some other client code is going to be wondering why its component has suddenly failed!?! Only Windsor is able to make the Disposal decision for you.
Nice blog post Krzysztof (won't let me post link!)
In our app we've made everything transient, apart from a couple of singletons. Transient seems to be the simplest model (as long as everyone understands you must 'Release rather than Dispose'). If you have a mock container in your tests, you can set an expectation that Release is called for each component your mock resolves, and I've also heard that transient has fewer performance issues (??) than other modes? The code is certainly more portable.
Last but not least, if you have a memory leak and you need to work what and why something isn't being collected by the GC, check out Tess Ferrandez' fab tutorial series on windbg
http://blogs.msdn.com/b/tess/archive/2008/04/03/net-debugging-demos-lab-7-memory-leak-review.aspx ... the culprit may be somewhere unexpected!
Related
I have a .net 4 web api with many controllers that all inherit from the same base controller. This base controller has a method that gets the database connection string and uses it to instantiate a new instance of DbContext. The DbContext is then passed to 10+ repositories which all use that instance of DBContext.
The base controller is doing the following:
public IRepository Repository { get; set; }
public BaseController(IRepository repository)
{
this.Repository = repository;
}
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
this.Repository = IRepositoryFactory.GetRepository();
}
public static class IRepositoryFactory
{
public static IRepository GetRepository()
{
// **gets database connectionString**
var context = new DbContext(connectionString)
// this passes context to all the 10+ repositories using same instance
return new IDataRepository(context);
}
}
Is having the base controller instantiate a new instance of DbContext on every api call causing the DbContext to never be reused between calls. In .net core you use the startup class to tell DbContext which database to use, but I don't believe you can do that in .net 4. I am afraid that these new instances of DbContext aren't being used like a Singleton and thus there is no caching going on, causing a lot of unnecessary database hits. Is there a better way to tell DbContext it's connection string and use it without created new instances of DbContext in the BaseController which gets hit on every controller?
For web applications you should leverage a IoC container to manage dependencies and lifetime scoping. Most of these can be wired directly into MVC to instantiate controllers, resolve references to dependencies such as Repositories, and their dependencies including the DbContext or wrappers like Unit of Work implementations. By default the IoC container should be scoping dependency lifecycles to the Request, so if you have 3 repositories spun up to serve a controller call, they would all receive the same reference to the DbContext to service a request.
If you haven't worked with an IoC container / Dependency Injection, I would recommend having a look at Autofac or Unity. Other common, though older ones include Castle Windsor & Ninject. ASP.Net Core has it's own DI extensions as well. I personally recommend Autofac as it is mature, but fairly young so it's designed around modern paradigms such as Generics and Fluent structure. It also has quite good documentation.
DbContext's should be short-lived, but if you are using several repositories, sharing a single instance for all repository calls is almost always advisable so that entity references can be shared between the repositories, and changes are saved as part of one operation. (Committing or rolling back all for one or none at all.) Separate DbContext instances require complicated code to detach and attach entities to share entities between repositories, and explicit transaction handling to guard operations. Personally I use the repository pattern as a separation for testing in isolation, though I avoid the generic repository pattern. I utilize Mehdime's DbContextScope patterns for Unit of Work which gives me more control over the unit of work as opposed to using the Dependency Injection to manage the lifetime of the DbContext.
Singleton instances of DbContexts for web applications, or any application should be avoided. Firstly, EF does not synchronize data with the database. Any cached entities can easily become stale so the longer a context is alive, the more stale overwrites or exceptions for row version checks (if you have 'em) will be occurring. The caching/tracking features of EF also result in increased memory usage as well as performance degradation as EF wants to check caches for object references and related dependencies with every query. This can lead to some odd behaviour when lazy loading is disabled where EF will populate references that happen to be cached which might not reflect complete sets of data.
I am new to dependency injection and have been doing some reading about it, both on StackOverflow and elsewhere. In practice I am having trouble with using it correctly.
To explain the problem, here's a basic situation where I am not sure how to use DI:
Suppose I have some object that is going to be used in several different classes. However, in order for this object to be usable, it needs certain parameters that I don't have at start-up.
A conceivable way that I can see to do this using DI is to create a blank instance of this object, a method to initialize it with the necessary parameters, and a flag for whether or not it is initialized.
To me, this feels like a hack, because the object shouldn't really exist yet and I am just passing a container around, waiting for the responsible code to initialize it. Is this how it is meant to be done, or am I missing the point?
That is indeed a pretty tough thing to get one's head around when getting started with DI, and something that also isn't easily explained.
Your notion that creating a "blank" object that will be initialized later via a method might be a suboptimal solution is correct - an object should be able to do its work at any time; Initialize() methods are what Mark Seemann calls "temporal coupling" in his book Dependency Injection in .NET. This is an anti-pattern that makes the code using the object dependent on the inner workings of that object and thus breaks encapsulation.
The question is when the required information becomes available, what the "responsible code to initialize it" is, and where it gets the information from - and also how it gets access to the object to initialize it. Ideally, this initializing code would itself be injected into your object, and whenever your object's methods/properties are accessed, it requests initialization from that other dependency.
Also, what happens if the IsInitialized flag returns false? Is that still a valid program state?
In general, as an object in a dependency injected object graph, I should either know all my "configuration" data on creation, or know someone who can give it to me (that someone is another object injected as a dependency).
It might help if you could provide a bit more detail about what kind of parameters the object needs and where they need to come from.
Edit
What you're describing in your comment is pretty much exactly my first encounter with this kind of issue; there's a question somewhere here on SO that I posted back then.
The important thing is to build individual classes (usually, there may be exceptions, but what those are is a matter of experience) in such a way that you assume everything the class needs is present. When the program is running, there need to be other classes then that make sure that assumption will not fail.
Setter injection is something I generally try not to have to avoid said temporal coupling; according to Mark Seemann, setter injection should usually only be used when you already have a good default in place that you just overwrite through the setter. In this case, though, the object would not be able to function properly without that dependency.
This may not be the most elegant way to do this (I usually have the luxury to apply DI in pretty closed code-only environments without having to worry about a UI), but it would work (kind of - it compiles, but is still pseudo code):
public class MainForm
{
private readonly IDataManager _dataManager;
private readonly IConnectionProvider _connectionProvider;
private readonly IConnectionReceiver _connectionReceiver;
public MainForm(IDataManager dataManager, IConnectionProvider connectionProvider, IConnectionReceiver connectionReceiver)
{
this._dataManager = dataManager;
this._connectionProvider = connectionProvider;
this._connectionReceiver = connectionReceiver;
}
public void btnConnect_Click()
{
IConnection connection = this._connectionProvider.GetConnection();
if (null != connection)
{
this._connectionReceiver.SetConnection(connection);
this.SetFormControlsEnabled(true);
}
}
private void SetFormControlsEnabled(bool doEnable)
{
}
}
public interface IConnectionProvider
{
IConnection GetConnection();
}
public interface IConnectionReceiver
{
void SetConnection(IConnection connection);
}
public interface IConnection
{
IConnectionWebService ConnectionWebService { get; }
}
public class ConnectionBridge : IConnection, IConnectionReceiver
{
private IConnection _connection;
#region IConnectionReceiver Members
public void SetConnection(IConnection connection)
{
this._connection = connection;
}
#endregion IConnectionReceiver Members
#region IConnection Members
public IConnectionWebService ConnectionWebService
{
get { return this._connection.ConnectionWebService; }
}
#endregion
}
public interface IConnectionWebService {}
public interface IDataManager { }
public class DataManager : IDataManager
{
public DataManager(IConnection connection)
{
}
}
So, MainForm is the thing that holds it all together. It starts out with its controls disabled, because it knows they need a working IDataManager and that will (by convention) need a connection. When a "connect" button is clicked, the form asks its IConnectionProvider dependency for a connection. It does not care where that connection comes from; the connection provider might display another form to ask for credentials or maybe just read them from a file.
Then the form knows that the connection has to be passed on to the IConnectionReceiver instance, and after that all controls can be enabled. This is not by any DI principle, this is just how we have defined that MainForm works.
The data manager on the other hand has everything it needs from the start - an IConnection instance. That can't do what it's supposed to do at first, but there is other code preventing that from causing problems.
ConnectionBridge is both a decorator for the actual IConnection instance and an adapter decoupling connection acquisition from connection consumption. It does that by employing the Interface Segregation Principle.
As a note on the side, be aware that while Dependency Injection is an important technique, it is only one of several principles you should follow to write what is known as "clean code". The most well known are the SOLID principles (of which DI is one), but there are others like Command-Query-Separation (CQS), "Don't repeat yourself" (DRY) and the Law of Demeter. On top of all that, practice unit testing, precisely Test Driven Development (TDD). These things really make a tremendous difference - but if you're taking up DI of your own accord, you're already off to a good start.
I agree with what GCATNM said and i would like to add that whenever i feel there is an object like this i go and use one of the Factory pattern variants (be it an Abstract Factory, Static Factory, etc ..) and i would inject the factory with the source of the configuration information for this object. So as Marc Seemann also said and i am not quoting: Factories are a great companion of Dependency Injection and you will need them occasionally.
I have some "caching" objects in my application, that get a IRepository (custom repository pattern contract) by dependency injection (Ninject). Those objects only uses the repository once, but they have a Refresh function that forces the owner to refresh itself. They are singletons, are created only once, and a ManualResetEvent ensures that all requests are blocked till it is loaded.
The IRepositories are EF CodeFirst based, so is it OK just to simply ensure the connection is closed and keep the reference to the DbContext there forever?
I have disabled the proxies and the lazy loading, so... is OK to have long references from the root of the caching object to hundreds of these cached POCO entities?
Cheers.
We reference to comments from Julie Lerman,
http://msdn.microsoft.com/en-us/magazine/ee532098.aspx?sdmr=JulieLerman
the recommendation is to have several/many smaller contexts and in the case of web scenarios create a new context each call.
Although she writes about Second-Level Caching in the Entity Framework and AppFabric.
Over time, the context would be contain many objects and the performance would decline accordingly.
I think this site has some good tips on EF performance.
eg generated views.
http://msdn.microsoft.com/en-us/data/hh949853
my personal recommendation, that I cant claim is best practice, but from someone who is concerned about performance, is that small bounded context each call is a solid long term compromise.
Use generated views to keep the initial load time as small as possible.
you could potentially manage a permanent DBContext in such a way as to drop unused objects from the context. Or use a caching library with events to do so. Not a small task.
I would be interested in the solution you finally select. please post.
Finally the best solution I found is to create a new kind of wrapper:
public class Generator<T> where T : IDisposable
{
readonly Func<T> _generate;
public Generator(Func<T> generate)
{
_generate= generate;
}
public T Generate()
{
return _generate();
}
}
And create a binding more or less this way:
// Dependency Injection bindings declaration section
DI.Bind<Generator<IRepository>>()
.To(()=> new Generator<IRepository>(()=> DI.Get<IRepository>()));
Therefore, in long lived objects that needs to just create and destroy the element, I can ask for a Generator<IRepository> service, rather than IRepository. Therefore, every time I need to refresh, I would just create a new IRepository, without knowing how it is build under the hood:
using (var repository = repositoryGenerator.Generate())
{
repository.DoStuff();
}
It works like a charm so far.
Actually, I have added this feature to my DI framework. I can now bind IAnything and later on request for Generator, and the framework will give me the fully ready object using this technique How to create a Func<> delegate programmatically
Cheers.
I'm having trouble getting the windsor container and entity framework working together and it may be due to a problem I've introduced myself but the net result is that I'm getting a terrible memory leaks caused.
I have my application set up with an EDMX and Repositories and Services and those and the objectcontext are set to perwebrequest in the windsor configuration file I use. However when I look at the memory usage in ANTS memory profiler I see that the object context cache is still being held onto as a reference with the cache despite confirming that Dispose has been called.
And each request more dynamic proxies are getting stuck in memory. If anyone else has managed to get themselves in a pickle like this and can offer me advice to get out of it, it would be greatly appreciated.
I've managed to track down and resolve the problem by changing the release settings on the kernal for the windsor container to:
_container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();
It seems although the windsor container calls the dispose method of perwebrequest components it still hangs on to a reference of them which prevents them being garbage collected.
In this case the object it was holding a reference to was of type ObjectContext. Unfortunately despite disposing of this object the all the dynamic proxies cached in this object still remain effectively meaning that a copy of my database (or at least the parts I was accessing) was being added to memory each request causing it to ramp up.
You are probably not disposing objects correctly. Try using "Using" blocks.
Cannot say much more without seeing the code.
I had the same problem.
After investigation it seemed that I was missing a call to _container.Release(controller) in my Controller Factory:
public override void ReleaseController(IController controller)
{
_container.Release(controller);
var disposable = controller as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
However, I was also using Windsor 2.1 and adding _container.Release(controller) did not do anything for me.
After updating to v3.1 it seems to work.
Hope this helps.
p.s. ANTS Memory Profiler - lifesaver!
I've ran into a rather hairy problem. There is probably a simple solution to this but I can't find it!
I have a custom HttpHandler that I want to process a request, log certain info then enter the details in the database. I'm using NUnit and Castle Windsor.
So I have two interfaces; one for logging the other for data entry, which are constructor injected. I quickly found out that there is no way to call the constructor as the default parameterless constructor is always called instead.
So I thought I would use Setter injection and let Castle windsor sort it out. This actually works as when I use container.Resolve<CustomHttpHandler>(); I can check that the logger is not null. (In Application_Start in Global.asax.cs)
The problem is although Castle Windsor can create the instance the http application is not using it??? I think??
Basically the whole reason for doing it this way was to be able to test the logger and data repository code in isolation via mocking and unit testing.
Any ideas how I can go about solving this problem?
Thanks!
Not possible, at least not directly. IHttpHandler objects are instantiated by the ASP.NET runtime and it doesn't allow Windsor to get involved in its creation. You can either:
Pull dependencies, by using the container as a service locator.
Set up a base handler that creates, injects and delegates to your own handlers (see how Spring does it)
Use the container as a service locator for another service that handles the entire request (as saret explained)
What you could do is have the HttpHandler call out to another object that actually handles the request. so in your HttpHandler's ProcessRequest method you would do something like this:
public void ProcessRequest(HttpContext context)
{
var myHandlerObject = container.Resolve<HandlerObject>();
myHandlerObject.ProcessRequest(context or some state/info that is required)
}