I have a very similar project (except that I do not use Caliburn) and try to figure out how to do it. I came up with one method that works well for injecting a constructor using the Ninject InScope () method.
I have a static IoC class that wraps access to the Ninject core. Since all dependencies are entered into the constructor, the context makes sense only when creating an object. Therefore, it doesn't matter what is provided for the context, but Guid feels like a safe choice. Program.OpenSession () is a static method for opening a new ISession.
public static class Ioc { private static readonly IKernel _kernel; static IoC() { _kernel = new StandardKernel(); _kernel.Load(new ContextModule()); } private static object _context; public static T ResolveInContext<T>(object context) { _context = context; var result = _kernel.Get<T>(); _context = null; return result; } private class ContextModule : NinjectModule { public override void Load() { Bind<ISession>().ToMethod(x => Program.OpenSession()).InScope(x => _context); Bind<frmCompanyViewer>().ToSelf().InScope(x => _context); } } }
Using:
var frm = IoC.ResolveInContext<frmCompanyViewer>(Guid.NewGuid());
Signature of the form constructor:
public frmCompanyViewer(ISession session, ICompanyRepository companyRepository)
I have verified that using InScope on bindings to build the Repository company, the same ISession is also used, which is used to build frmCompanyViewer. If I remove InScope, then two ISessions are used.
Edited to add: This will also work, see comments. This must be made thread safe for real use. I changed the method name to ConstructInContext to clarify that context only applies when building an object.
public static T ConstructInContext<T>() { _context = Guid.NewGuid(); var result = _kernel.Get<T>(); _context = null; return result; }
source share