Ninject, Web API and MVC 4 Filter Binding disposing datacontext - asp.net-mvc-4

I have an issue with my datacontext getting disposed every once in a while in one of my filters attached to my web api controllers. Is this the correct way to setup a filter for my Web API controllers and why does my datacontext get disposed sometimes?
The operation cannot be completed because the DbContext has been disposed.
Global.asax
GlobalConfiguration.Configuration.Filters
.Add(new ApiValidationFilter(kernel.Get<IApiAuthenticationService>()));
kernel.Bind<IDatabaseFactory>()
.To<DatabaseFactory>()
.InScope(q => HttpContext.Current ?? StandardScopeCallbacks.Thread(q));
ApiValidationFilter.cs
public class ApiValidationFilter : System.Web.Http.Filters.IActionFilter
{
private readonly IApiAuthenticationService _apiAuthenticationService;
public ApiValidationFilter(
IApiAuthenticationService apiAuthenticationService)
{
_apiAuthenticationService = apiAuthenticationService;
}

You should be using the Filter binding syntax, then Ninject will handle the the filter lifetime, and it will also handle the constructor injection of the filter.
https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations
I would also let Ninject handle managing the lifetime of the data conext as well, instead of using a factory.
kernel.Bind<MyContext>().ToSelf().InRequestScope();
Alternatively, if you want better testability you can derive your context from an interface and bind to that. The InRequestScope makes sure the context lives for the entire web request, and it will automatically get disposed when the request is done. You don't have to remember to do so, and there won't be any memory leaks by holding onto a request longer than a single request.
You can see an example here:
ASP.NET MVC 3 and Global Filter Injection

I eventually had to resort to the following, nothing worked.
var apiRepository = new ApiRepository(new DatabaseFactory());
var apiAuthenticationService = new ApiAuthenticationService(apiRepository, new UnitOfWork(new DatabaseFactory()), new ValidationProvider(null));

Related

DryIoc ASP.Net Core 3.1 DbContext store in Scope Container

I am using DryIoc (last release version) for Dependency Injection.
In my application (Asp.net Core 3.1), I am using Entity Framework.
My AppDbContext hinerits DbContext and implements IDisposable
I also use UnitOfWork pattern and the class is disposable.
These two objects are declared as Transient.
I follow the documentation of DryIoc that explains the context with Transient Disposable objects:
https://github.com/dadhi/DryIoc/blob/master/docs/DryIoc.Docs/ReuseAndScopes.md
For my AppDbContext, I resolve this service manually. Same thing for my UnitOfWork. At the end I call Dispose method.
But these two instances are not destroyed and are stored in the Singleton Scope of the DryIoc Container.
I did some tests and use JetBrain dotMemory.
My test is to call 100 times a method
Call controler
open UnitOfWork
create AppDbContext
call database to get my data
close / dispose objects.
At the end, I have 100 times my AppDbContext and my UnitOfWork in the scope of the container:
I tried a lot of combinations of creation of container but each time, it is the same thing:
var container = new Container(rules =>
rules.With(propertiesAndFields: request => request.ServiceType.Name.EndsWith("Controller") ? PropertiesAndFields.Auto(request) : null)
// .WithoutThrowOnRegisteringDisposableTransient()
// .WithTrackingDisposableTransients()
.WithoutThrowIfDependencyHasShorterReuseLifespan())
.WithDependencyInjectionAdapter(services);
Result: memory is growing up fast because of these two kind of objects stored in the scope.
If I comment .WithoutThrowOnRegisteringDisposableTransient(), my code is still working (I thought an exception would be thrown)
I tried also to declare these services as Scoped (for each http request) but it does not work because I don't create scope for each query. (Exception thrown and a scope is automatically opened per each web request by Asp .Net Core framework).
Maybe I need to dispose scope at the end of each request?
How could I force destruction of objects?
Thanks to the author of the lib, I found solution:
https://github.com/dadhi/DryIoc/issues/261

Entity Framework and WCF (Returning Entities Attached To Context)

I have a WCF service that calls the following method in one of my Repository objects to create a new sale object in the database
public static Sale New(Sale sale)
{
using (var ctx = new DBcontext())
{
ctx.Sales.AddObject(sale);
ctx.SaveChanges();
return sale;
}
}
The WCF method calling this looks like this
public Sale SaleNew(Sale sale)
{
return SaleRepository.New(sale);
}
When I call this from a client application I get the following error
"The underlying connection was closed: The connection was closed unexpectedly."
If I step through all the code seems to run fine and the record gets insterted into the database. If I add the following line to my repository method after the SaveChanges it works fine
ctx.Detach(sale);
Is the exception happening because I'm disposing the context as soon as the method returns? Is using the entity context in this way bad practise ie disposing of it straight away? I'm only doing this because its SOA and pretty much stateless so all my repository methods create the context return the value and dispose the context. Anything that is passed in will either get added to the context or re-attached.
As advised I turned on tracing in WCF and watched what was happening. There was a proxy exception occurring. In this case as I'm using my own POCO objects I don't really want proxy objects so I set the ContextOptions.ProxyCreationEnabled property in my DatabaseContext to false and it now works fine.
1) Is using the entity context in this way bad practise ie disposing of it straight away?
No, that's how I do it - and I believe it is the proper way of doing it. But creating context can be expensive and with EF we are stuck with no ideal way of reusing the context.
2) ctx.Detach(sale);
This as far as I know should not be required for what you are doing although I have had loads of issues with attaching and detaching when I reuse the same entities. This should be only needed if you need to re-attach to context. Are you using Lazy-Loading?

IQueryable Repository with StructureMap (IoC) - How do i Implement IDisposable?

If i have the following Repository:
public IQueryable<User> Users()
{
var db = new SqlDataContext();
return db.Users;
}
I understand that the connection is opened only when the query is fired:
public class ServiceLayer
{
public IRepository repo;
public ServiceLayer(IRepository injectedRepo)
{
this.repo = injectedRepo;
}
public List<User> GetUsers()
{
return repo.Users().ToList(); // connection opened, query fired, connection closed. (or is it??)
}
}
If this is the case, do i still need to make my Repository implement IDisposable?
The Visual Studio Code Metrics certainly think i should.
I'm using IQueryable because i give control of the queries to my service layer (filters, paging, etc), so please no architectural discussions over the fact that im using it.
BTW - SqlDataContext is my custom class which extends Entity Framework's ObjectContext class (so i can have POCO parties).
So the question - do i really HAVE to implement IDisposable?
If so, i have no idea how this is possible, as each method shares the same repository instance.
EDIT
I'm using Depedency Injection (StructureMap) to inject the concrete repository into the service layer. This pattern is followed down the app stack - i'm using ASP.NET MVC and the concrete service is injected into the Controllers.
In other words:
User requests URL
Controller instance is created, which receives a new ServiceLayer instance, which is created with a new Repository instance.
Controller calls methods on service (all calls use same Repository instance)
Once request is served, controller is gone.
I am using Hybrid mode to inject dependencies into my controllers, which according to the StructureMap documentation cause the instances to be stored in the HttpContext.Current.Items.
So, i can't do this:
using (var repo = new Repository())
{
return repo.Users().ToList();
}
As this defeats the whole point of DI.
A common approach used with nhibernate is to create your session (ObjectContext) in begin_request (or some other similar lifecycle event) and then dispose it in end_request. You can put that code in an HttpModule.
You would need to change your Repository so that it has the ObjectContext injected. Your Repository should get out of the business of managing the ObjectContext lifecycle.
I would say you definitely should. Unless Entity Framework handles connections very differently than LinqToSql (which is what I've been using), you should implement IDisposable whenever you are working with connections. It might be true that the connection automatically closes after your transaction successfully completes. But what happens if it doesn't complete successfully? Implementing IDisposable is a good safeguard for making sure you don't have any connections left open after your done with them. A simpler reason is that it's a best practice to implement IDisposable.
Implementation could be as simple as putting this in your repository class:
public void Dispose()
{
SqlDataContext.Dispose();
}
Then, whenever you do anything with your repository (e.g., with your service layer), you just need to wrap everything in a using clause. You could do several "CRUD" operations within a single using clause, too, so you only dispose when you're all done.
Update
In my service layer (which I designed to work with LinqToSql, but hopefully this would apply to your situation), I do new up a new repository each time. To allow for testability, I have the dependency injector pass in a repository provider (instead of a repository instance). Each time I need a new repository, I wrap the call in a using statement, like this.
using (var repository = GetNewRepository())
{
...
}
public Repository<TDataContext, TEntity> GetNewRepository()
{
return _repositoryProvider.GetNew<TDataContext, TEntity>();
}
If you do it this way, you can mock everything (so you can test your service layer in isolation), yet still make sure you are disposing of your connections properly.
If you really need to do multiple operations with a single repository, you can put something like this in your base service class:
public void ExecuteAndSave(Action<Repository<TDataContext, TEntity>> action)
{
using (var repository = GetNewRepository())
{
action(repository);
repository.Save();
}
}
action can be a series of CRUD actions or a complex query, but you know if you call ExecuteAndSave(), when it's all done, you're repository will be disposed properly.
EDIT - Advice Received From Ayende Rahien
Got an email reply from Ayende Rahien (of Rhino Mocks, Raven, Hibernating Rhinos fame).
This is what he said:
You problem is that you initialize
your context like this:
_genericSqlServerContext = new GenericSqlServerContext(new
EntityConnection("name=EFProfDemoEntities"));
That means that the context doesn't
own the entity connection, which means
that it doesn't dispose it. In
general, it is vastly preferable to
have the context create the
connection. You can do that by using:
_genericSqlServerContext = new GenericSqlServerContext("name=EFProfDemoEntities");
Which definetely makes sense - however i would have thought that Disposing of a SqlServerContext would also dispose of the underlying connection, guess i was wrong.
Anyway, that is the solution - now everything is getting disposed of properly.
So i no longer need to do using on the repository:
public ICollection<T> FindAll<T>(Expression<Func<T, bool>> predicate, int maxRows) where T : Foo
{
// dont need this anymore
//using (var cr = ObjectFactory.GetInstance<IContentRepository>())
return _fooRepository.Find().OfType<T>().Where(predicate).Take(maxRows).ToList();
And in my base repository, i implement IDisposable and simply do this:
Context.Dispose(); // Context is an instance of my custom sql context.
Hope that helps others out.

NHibernate Session gets disposed off on each wcf service method call

I am using Wcf in Sharp Architecture. I have configured my project following northwind sample using WcfSessionStorage etc. I have a method in the wcf service that gets a list of business object using Repository<>.GetAll(). I am testing the service method using WcfTestClient. When the method is called the very first time, everything works fine. However on the subsequent call, I get the following exception on the Repository<>.GetAll() method
[System.ObjectDisposedException]
Session is closed!
Object name: 'ISession'
It seems like the NHibernate session gets disposed after each call. I have got around this problem by decorating my service with the following attribute
[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}
However this means, an instance of the service will be created on each call that in turn will create a new nhibernate session etc. In my scenario there is no need of creating a new service instance per call and I think its an expensive process and not the right solution. I would like to know what is the best practice in my scenario and how to get this thing work with creating a new service instace per call.
Thanks
Nabeel
The easiest way is to create a new instance every time and it's not an expensive process, because creating a new object in .NET is like 0.00000000000000001 second (I read that on Ayande's blog or somewhere).
I use Autofac DI in my projects and I usually make ISession as container scoped (one per request). And then every class that uses (directly or indirectly) ISession has to be container scoped or lower (factory scoped == every class usage get's a new instance). If a class that uses ISession is higer scoped (session scoped == singleton) you'll run into problems that you currently have.
If your service is singleton service:
At first run the service is created, this service uses ISession, which should be container scoped, and it is on the first run.
The next request to service (service is now created) has still a reference to created ISession (which was closed on previous end request), so now it's closed.
I don't recomend using the same ISession that you'll open/close (it's not recomended in the NHibernate documentation), just use container scoped (I do and I don't have any performance issues), or you should create ISession manually in every method in your service like:
using(ISession s = ISessionFactory.OpenSession())
using(ITransaction t = .....)
....
But that isn't nice at all...
Please take a look at my answer to my own similar question: WCF/S#arpArch: underlying ISession is closed after the first call within a request.
#dmonlord is right that the creation of additional session instances within the same request is very cheap in this case.

Managing NHibernate ISession with Autofac

Does anyone have any tips or best practices regarding how Autofac can help manage the NHibernate ISession Instance (in the case of an ASP.NET MVC application)?
I'm not overly familiar with how NHibernate sessions should be handled. That said, Autofac have excellent instance lifetime handling (scoping and deterministic disposal). Some related resources are this article and this question. Since you're in ASP.Net MVC land make sure you also look into the MVC integration stuff.
To illustrate the point, here's a quick sample on how you can use Autofac factory delegates and the Owned generic to get full control over instance lifetime:
public class SomeController
{
private readonly Func<Owned<ISession>> _sessionFactory;
public SomeController(Func<Owned<ISession>> sessionFactory)
{
_sessionFactory = sessionFactory;
}
public void DoSomeWork()
{
using (var session = _sessionFactory())
{
var transaction = session.Value.BeginTransaction();
....
}
}
}
The container setup to get this to work is quite simple. Notice that we don't have to do anything to get the Func<> and Owned<> types, these are made available automatically by Autofac:
builder.Register(c => cfg.BuildSessionFactory())
.As<ISessionFactory>()
.SingleInstance();
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession());
Update: my reasoning here is that, according to this NHibernate tutorial, the lifetime of the session instance should be that of the "unit of work". Thus we need some way of controlling both when the session instance is created and when the session is disposed.
With Autofac we get this control by requesting a Func<> instead of the type directly. Not using Func<> would require that the session instance be created upfront before the controller instance is created.
Next, the default in Autofac is that instances have the lifetime of their container. Since we know that we need the power to dispose this instance as soon as the unit of work is done, we request an Owned instance. Disposing the owned instance will in this case immediately dispose the underlying session.
Edit: Sounds like Autofac and probably other containers can scope the lifetime correctly. If that's the case, go for it.
It isn't a good idea to use your IoC container to manage sessions directly. The lifetime of your session should correspond to your unit of work (transaction boundary). In the case of a web application, that should almost certainly be the lifetime of a web request.
The most common way to achieve this is with an HttpModule that both creates your session and starts your transaction when a request begins, then commits when the request has finished. I would have the HttpModule register the session in the HttpContext.Items collection.
In your IoC container, you could register something like HttpContextSessionLocator against ISessionLocator.
I should mention that your generic error handling should locate the current session and roll back the transaction automatically, or you could end up committing half a unit of work.