Ninject dispose order with InRequestScope - asp.net-mvc

Just started playing with ninject - and I can't get past this issue. Consider this setup:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDataTransaction>().To<DataTransaction>().InRequestScope();
kernel.Bind<IdbAnalytics>().To<dbAnalytics>().InRequestScope();
kernel.Bind<IdbMembership>().To<dbMembership>().InRequestScope();
kernel.Bind<IAnalyticsWork>().To<AnalyticsWork>().InRequestScope();
kernel.Bind<IMembershipWork>().To<MembershipWork>().InRequestScope();
kernel.Bind<ILog>().To<Log>().InRequestScope();
...
}
With Log being injected into the above classes:
public class AnalyticsWork : IAnalyticsWork, IDisposable
{
private readonly IdbAnalytics _Context;
private readonly ILog _Log;
public AnalyticsWork(IdbAnalytics Context, ILog Log)
{
_Context = Context;
_Log = Log;
_Log.Write(LogEntryType.DEBUG, "Object Created");
}
...
}
This issue is the Log object gets disposed of ahead of the other objects (AnalyticsWork / MembershipWork). Is there any way to set the order that items should be disposed of? Or is this setup flawed?

I do not use NInject, but it sounds to me that you are registering the Log concrete as shared or per web request (as per the InRequestScope might indicate, again I do apologize for not using NInject so I am not sure what that does).
For all of the loggers I've used, NLog, Log4Net, MS' Logging Application Block, etc - they all require Transient registration, not Scoped, because they take the superclass that initiated them to write out in the log as the calling class.
As far as dispose order, I don't think you can control that with any IoC container because the object cannot be disposed in different orders if another class still has a reliance. I ran into the same issues when I first started with IoC Containers years ago and thought, "Yeah, I'll register everything as scoped!" Hehe, that didn't work out very well.
I would say your objects just need to be registered differently. Only scope the items you really need scoped, everything else as transients or singletons. I usually follow the pattern of:
Code everything singleton and code thread-safe.
If not thread-safe make it a transient and register it as such.
If I not using a unit-of-work pattern with my ORM, I will typically register my ORM containers as Scoped so they can track the object changes for the life of the request, and SaveChanges() latter (e.g. Entity Framework 4, or NHibernate's Session, etc).

Related

Dependency injection in `ActionFiliter` vs. calling `Activator.CreateInstance()`

Requiring to sometimes use dependency injection in ActioFilter or other attributes running before or after an action API or result is inevitable. However, it is carried out through passing the type to be injected to the attribute using the typeof keyword. In order to simplify the case, when having various implementations for an interface, I have found it much simpler to manually instantiate the type than using the built-in dependency injection framework. For example:
public TestAttribute: Attribute, IActionFilter {
private Type injectionType;
public TestAttribute(Type injectionType){
...
}
...
public void OnActionExecuting(ActionExecutingContext context) {
InjectedTypeInterface injectedTypInterface = (InjectedTypeInterface) Activator.CreateInstance(injectedType, arg1, arg2, ...);
...
}
}
I want to know, from the point of view of other people here, that would this approach cause problems that using the built-in dependency injection framework would not? (Injected implementation will be always Transient in this case and not Scoped or Singleton)
I don't recommend doing the route of Activator.CreateInstance, here are some reasons why to avoid it and stick with the official way:
You'd need to pass in all instances of the parameters (i.e. of the type you want to instantiate has other dependencies) to it
The instance created this way isn't tracked by the scoped container. This also means, it won't automatically get disposed (Updated note this of course will only happen if the service implements IDisposable interface) at the end of the request and instead be disposed at some indeterminable time in future, when the GC kicks in and will keep resources open for longer then intended (i.e. holding connection or file handle open for longer then intended) unless you dispose it explicitly
Like you already recognized, you can't do so with scoped and singleton instances
For your concrete examples, there are easier ways to get a specific instance from DI - aside from the official supported ways (Filters - Dependency Injection) - you can also resolve from HttpContext, assuming you have access to it in the type of filter you are using.
For ActionFilter/IActionFilter
public void OnActionExecuting(ActionExecutingContext context) {
InjectedTypeInterface injectedTypInterface = context.HttpContext
.RequestServices.GetService<InjectedTypeInterface>();
...
}

Dispose DbContext in MVC Controller, which way "better"?

In MVC 5, the scaffolding codes will have something like:
public class MyController : Controller
{
private MyContext db = new MyContext();
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
otherwise, I need to have
using (var db = new MyContext())
{...}
in each action.
The codes look good, so I don't need to use using in each action. However, is this subject to preference of programmers, or such style has some advantage over using in each action that needs to use the dbcontext?
Both solution are good - both solution will dispose db context. But in my opinion the second option will be better - you create db context just where you have to.
But what if another class (some service class) also uses db context. It is good practice to have one db context for the whole web request. In that case you should pass previous created db context to all classes that use db context to prevent creating new db context in all clases. So I will consider usage of IoC containers. IoC container will resolve your dependencies and also will mange object lifetime. Bellow
I listed a few IoC containers:
Castle Windsor
Spring Framework
StructureMap
For simple scenarios calling Dispose (or using Using) is not necessary at all :)
"The default behavior of DbContext is that the underlying connection is automatically opened any time is needed and closed when it is no longer needed."
From here:
http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext/
In terms of best practices, you should absolutely use the template scaffolded stuff and not mess with the using(){} pattern unless you have some really good overriding reason. Both solutions produce the same result, but both are not good solutions. The reason why the template has a single DbContext is to make it easier to test - heres an example:
public class SomeController : Controller
{
private ApplicationDbContext db;
public AccountController()
{
db = new ApplicationDbContext();
}
public AccountController(ApplicationDbContext context)
{
db = context;
}
}
The first constructor with no arguments is that which is used in production and automatically creates a new db context based on the app config file. The second allows you to inject a mocked db context when you are doing unit testing.
At the end of the day, this question and my answer isn't really about disposing db contexts - it's about why the code template designers chose to take the approach they did and why it will help you. You should read more on unit testing.
A Using statement calls the Dispose() method at the end of the Using block automatically. The Using statement calls the Dispose() method even if there was an error in the code.

How to refer to Entity Framework DbContext from MVC business objects?

I'm starting a new ASP.NET MVC project. In my last project, one of the biggest code smells was how I passed around the Entity Framework DbContext, stored it in HttpContext.Current, called SaveChanges() in my rendering event, and did all manner of (probably unseemly) related things.
Suppose that my unit of work always corresponds to a web request. What is the right way to create a DbContext, share that context to a business library (e.g. an assembly outside the MVC project responsible for processing some workflow activities), share result models back to my controller, and persist any changes?
I'll be honest, I don't know much about dependency injection. It sounds like it should be related, but I don't see how it would get me a shared context instance between my controller and my business processes in an external assembly.
If I only needed it from controllers, it would be easy. I'd stick to HttpContext. But now HttpContext has spilled over to my external library. Do I just define an interface that returns the current DbContext, and base an implementation of that on HttpContext?
Hope that's clear what I'm asking, as I'm a little lost.
Dependency injection definitely sounds like what you are after here. My preference is ninject so below is a bit of an example of how I do this with EF.
Install Ninject.MVC3 (available on nuget)
Go to \app_start\NinjectWebCommon.cs (added by the above package) and add the following to the RegisterServices method
kernel.Bind<MyContext>().ToSelf().InRequestScope(); //binding in the context in request scope, this will let us use it in our controllers
Inside a controller consume the context as follows
public class MyController : ....{
private readonly MyContext _context;
public MyController(MyContext context){ _context = context; }
//Do stuff with _context in your actions
}
This is a really simple example for you to try there are plenty of better ways to structure this as your application grows (such as ninject modules) but this will demonstrate how DI works.
A few things to note, Always make sure you bind the context in requestscope (or more frequently) as DBContext has a nasty habit of growing quite bit if it sticks around too long.
In terms of sharing it with your external stuff that can be injected too, eg
public class MyExternalLogic{
public MyExternalLogic(MyContext context){....}
}
public class MyController : ....{
private readonly MyContext _context;
public MyController(MyContext context, MyExternalLogic logic){ _context = context; ...}
//Do stuff with _context in your actions
}
In the above the same instance of DbContext will be used for both MyController and MyExternalLogic. Ninject will handle the creation of both objects.
There are also a bunch of other DI containers available which will give you very similar experiences. I highly recommend DI as it helps a lot with unit test-ability as well.
For some more examples of how I use Ninject to structure my MVC apps check out some of my projects on github, such as https://github.com/lukemcgregor/StaticVoid.Blog

The 'Permanent' SessionFactory, ASP.NET MVC and nHibernate

I've been building an application with Fluent nHibernate/ASP.NET MVC - and I've dug around and figured out that it's considered most appropriate practice to keep a 'permanent' SessionFactory open, and then use sessions for each request to the database. Okay, this sounds good...
I'm quite confused on how to accomplish this, though. Everything I find assumes an entire structured framework that uses some kind of IoC container system ...and that's just too advanced for what I have so far. Are there any more simple examples of how to implement this kind of design?
I've taken a look at Where can I find a good NHibernate and ASP.NET MVC Reference Application
And even read the book "ASP.NET MVC in Action", but it's example is just far more complicated than what I am trying to achieve. I thought a singleton model would work in the Application_Start of the 'global.asax' but that didn't yield the results I had hoped for. It would keep disposing of my factory and never recreating it.
You could expose the ISessionFactory as singleton:
public sealed class FactoryManager
{
private static readonly ISessionFactory _instance = CreateSessionFactory();
static FactoryManager()
{ }
public static ISessionFactory Instance
{
get { return _instance; }
}
private static ISessionFactory CreateSessionFactory()
{
// TODO: configure fluentnhibernate and create a session factory
}
}
Now you could use FactoryManager.Instance in your code:
using (var session = FactoryManager.Instance.OpenSession())
using (var tx = session.BeginTransaction())
{
// TODO: use the session here
tx.Commit();
}
Make a static GetSessionFactory method on your global MvcApplication class. This method initializes a session factory the first time it is called and stores it as a private static variable. Upon subsequent calls, it simply returns the static variable.
This method can also check to see if the object is null or disposed and recreate as necessary, though it shouldn't happen since the variable would be static and thus, stay alive for the duration of the application's lifetime.

What design pattern to locate my IUnitOfWork?

I've implemented a repository pattern with persistence ignorance. The repository implementation only interacts with my entity objects, IUnitOfWork and ITable<T> interfaces. The intention is that the IUnitOfWork isn't reused but represents a single transaction. So far, I've implemented in-memory as well as Linq-to-Sql versions of the IUnitOfWork and ITable<T>.
My problem is that due to the IUnitOfWork injection into the repository, I end up with needing to know how to instantiate a new IUnitOfWork where ever the repository is used. Since this is the primary piece that is supposed to be pluggable it feels like I've done something wrong. The general usage pattern is something like this:
FooUnitOfWork unitOfWork = new FooUnitOfWork();
Repository repos = new Repository(unitOfWork);
// ...act upon repos
unitOfWork.Save();
Now it appears that I need some other pattern to allow every repository usage in the app to obtain the correct unit of work (e.g. in-memory, L2S, etc.).
What is the most fitting pattern for this? I've looked at Fowler's discussion on the topic but none of his examples seem to be a clean fit. I already feel like the amount of abstraction that I have is more than I'd like so building yet another indirection seems excessive.
At the moment, I'm leaning toward some sort of app-wide provider which can be configured to produce the correct IUnitOfWork. Am I off-base or is this what is needed to truly be implementation agnostic?
Update: while this didn't really break down it ended up just producing a poor-man's IoC Container. I ended up just replacing all of these:
UnitOfWorkFactory.Create();
with the generalized Common Service Locator implementation:
Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IUnitOfWork>();
This allowed me to create a library which uses Dependency Injection without forcing all users to use the same IoC framework.
Perhaps I should use a very simple factory where I can set a callback? It could have a set of static methods on it like this:
public static class UnitOfWorkFactory
{
private static Func<IUnitOfWork> FactoryMethod;
public static IUnitOfWork Create()
{
if (UnitOfWorkFactory.FactoryMethod == null)
{
throw new InvalidOperationException("...");
}
return UnitOfWorkFactory.FactoryMethod();
}
public static void SetFactoryMethod(Func<IUnitOfWork> factory)
{
UnitOfWorkFactory.FactoryMethod = factory;
}
}
Where does this break down?
I would suggest using a Vistor pattern to discover the implementations of the IUnitOfWork interface.
[UnitOfWork(Name="foo")]
public class FooUnitOfWork : IUnitOfWork {}
Repository repo = new Repository("foo");
//stuff happens
repo.Save(); //or repo.Worker.Save();
Inside the repo instance a discovery factory finds the worker and creates it.

Resources