Getting AsyncController to work with Ninject - asp.net-mvc

I am trying to convert some actions within a controller to run asynchronously in an mvc project that is using ninject for dependency injection. I'm following the steps by inheriting AsyncController and changing the methods that correspond to the 'X' action to 'XAsync' and 'XCompleted' but the async action is not getting resolved. I'm confident that the issue has to do with ninject. I have tried to explicitly set ninject's Controller Action Invoker to 'AsyncControllerActionInvoker':
Bind<IActionInvoker>().To<AsyncControllerActionInvoker>().InSingletonScope();
but no luck. Has anyone managed to get Async actions working with ninject?
cheers,

Essentially the problem i was facing was that the default action invoker that is used by ninject doesnt support async actions and when you try to set the action invoker in a controller the default ninjectControllerFactory overrides it. I took the following steps to fix the problem:
1.In the injection mapping i added the following association:
Bind<IActionInvoker>().To<AsyncControllerActionInvoker>().InSingletonScope();
2.I created a custom controller factory that is basically ninject's controller factory with the only difference being that it doesn't overwrite the action invoker.
public class CustomNinjectControllerFactory : DefaultControllerFactory {
/// <summary>
/// Gets the kernel that will be used to create controllers.
/// </summary>
public IKernel Kernel { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="NinjectControllerFactory"/> class.
/// </summary>
/// <param name="kernel">The kernel that should be used to create controllers.</param>
public CustomNinjectControllerFactory(IKernel kernel) {
Kernel = kernel;
}
/// <summary>
/// Gets a controller instance of type controllerType.
/// </summary>
/// <param name="requestContext">The request context.</param>
/// <param name="controllerType">Type of controller to create.</param>
/// <returns>The controller instance.</returns>
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
if (controllerType == null) {
// let the base handle 404 errors with proper culture information
return base.GetControllerInstance(requestContext, controllerType);
}
var controller = Kernel.TryGet(controllerType) as IController;
if (controller == null)
return base.GetControllerInstance(requestContext, controllerType);
var standardController = controller as Controller;
if (standardController != null && standardController.ActionInvoker == null)
standardController.ActionInvoker = CreateActionInvoker();
return controller;
}
/// <summary>
/// Creates the action invoker.
/// </summary>
/// <returns>The action invoker.</returns>
protected virtual NinjectActionInvoker CreateActionInvoker() {
return new NinjectActionInvoker(Kernel);
}
}
3.In OnApplicationStarted() method I set the controller factory to my custom one:
ControllerBuilder.Current.SetControllerFactory(new customNinjectControllerFactory(Kernel));`
Hope this helps.

After much search i realized in addition to this, each controller needs to explicitly be set to use an Action Invoker that supports Async Actions.

Related

Converting from a repository factory to an IOC solutions for EF?

I have an application which borrows a lot of code from the John Papa Code Camper application. In his applicatione he uses a Repository factory to provide a new repository or an existing repository if one already exists in cache. To me this seems overly complicated and I am wondering if I could use Unity to do the same thing. Here's an example of the code that I am currently using:
In the UOW he has this code to get the repos:
public IRepository<Answer> Answers { get { return GetStandardRepo<Answer>(); } }
This code to call the repository provider:
protected IRepositoryProvider RepositoryProvider { get; set; }
protected IRepository<T> GetStandardRepo<T>() where T : class
{
return RepositoryProvider.GetRepositoryForEntityType<T>();
}
protected T GetRepo<T>() where T : class
{
return RepositoryProvider.GetRepository<T>();
}
The following respository provider:
public class RepositoryProvider : IRepositoryProvider
{
public RepositoryProvider(RepositoryFactories repositoryFactories)
{
_repositoryFactories = repositoryFactories;
Repositories = new Dictionary<Type, object>();
}
//public RepositoryProvider(RepositoryFactories repositoryFactories)
//{
// _repositoryFactories = repositoryFactories;
// Repositories = new Dictionary<Type, object>();
//}
/// <summary>
/// Get and set the <see cref="DbContext"/> with which to initialize a repository
/// if one must be created.
/// </summary>
public DbContext DbContext { get; set; }
/// <summary>
/// Get or create-and-cache the default <see cref="IRepository{T}"/> for an entity of type T.
/// </summary>
/// <typeparam name="T">
/// Root entity type of the <see cref="IRepository{T}"/>.
/// </typeparam>
/// <remarks>
/// If can't find repository in cache, use a factory to create one.
/// </remarks>
public IRepository<T> GetRepositoryForEntityType<T>() where T : class
{
return GetRepository<IRepository<T>>(
_repositoryFactories.GetRepositoryFactoryForEntityType<T>());
}
/// <summary>
/// Get or create-and-cache a repository of type T.
/// </summary>
/// <typeparam name="T">
/// Type of the repository, typically a custom repository interface.
/// </typeparam>
/// <param name="factory">
/// An optional repository creation function that takes a DbContext argument
/// and returns a repository of T. Used if the repository must be created and
/// caller wants to specify the specific factory to use rather than one
/// of the injected <see cref="RepositoryFactories"/>.
/// </param>
/// <remarks>
/// Looks for the requested repository in its cache, returning if found.
/// If not found, tries to make one using <see cref="MakeRepository{T}"/>.
/// </remarks>
public virtual T GetRepository<T>(Func<DbContext, object> factory = null) where T : class
{
// Look for T dictionary cache under typeof(T).
object repoObj;
Repositories.TryGetValue(typeof(T), out repoObj);
if (repoObj != null)
{
return (T)repoObj;
}
// Not found or null; make one, add to dictionary cache, and return it.
return MakeRepository<T>(factory, DbContext);
}
/// <summary>
/// Get the dictionary of repository objects, keyed by repository type.
/// </summary>
/// <remarks>
/// Caller must know how to cast the repository object to a useful type.
/// <p>This is an extension point. You can register fully made repositories here
/// and they will be used instead of the ones this provider would otherwise create.</p>
/// </remarks>
protected Dictionary<Type, object> Repositories { get; private set; }
/// <summary>Make a repository of type T.</summary>
/// <typeparam name="T">Type of repository to make.</typeparam>
/// <param name="dbContext">
/// The <see cref="DbContext"/> with which to initialize the repository.
/// </param>
/// <param name="factory">
/// Factory with <see cref="DbContext"/> argument. Used to make the repository.
/// If null, gets factory from <see cref="_repositoryFactories"/>.
/// </param>
/// <returns></returns>
protected virtual T MakeRepository<T>(Func<DbContext, object> factory, DbContext dbContext)
{
var f = factory ?? _repositoryFactories.GetRepositoryFactory<T>();
if (f == null)
{
throw new NotImplementedException("No factory for repository type, " + typeof(T).FullName);
}
var repo = (T)f(dbContext);
Repositories[typeof(T)] = repo;
return repo;
}
/// <summary>
/// Set the repository for type T that this provider should return.
/// </summary>
/// <remarks>
/// Plug in a custom repository if you don't want this provider to create one.
/// Useful in testing and when developing without a backend
/// implementation of the object returned by a repository of type T.
/// </remarks>
public void SetRepository<T>(T repository)
{
Repositories[typeof(T)] = repository;
}
/// <summary>
/// The <see cref="RepositoryFactories"/> with which to create a new repository.
/// </summary>
/// <remarks>
/// Should be initialized by constructor injection
/// </remarks>
private RepositoryFactories _repositoryFactories;
}
Is this something that I could use Unity for and if so can someone give me some hints on how I could create the repositories in Unity so that that they could be shared. Note that I have two types of repositories. A generic and a custom. Right now these are returned using GetStandardRepo and GetRepo. I would like if possible to have the mapping that decideds which repo I get inside my Unity config file so that it's clearly visible.
Here is the Unity Config I have so far:
container.RegisterType<RepositoryFactories>(new ContainerControlledLifetimeManager());
container.RegisterType<IRepositoryProvider, RepositoryProvider>();
container.RegisterType<IUow, Uow>();
container.RegisterType<Contracts.Services.IContentService, Services.ContentService>();
container.RegisterType<IAnswerService, AnswerService>();
Unity supports registering components "Per Request" in MVC projects. The first time a particular repository is served from the container it will be instantiated. Any subsequent requests for that repository during the same HTTP request will use this same repository rather than creating a new one.
You can read more about how this works using the link below. Basically, you're looking to control the lifetime scope of your objects as a singleton rather than for each dependency.
Unity Documentation on MSDN

Can I define custom attributes for proxy type in Castle Windsor

I have a class that I proxy it with Castle Dynamic Proxy. I want to add some custom Attributes to proxy methods (which is not defined in proxied class). Is this possible.
I want this because I want to generate ASP.NET Web API layer for my application's Service Layer. I proxied services (with inheriting from ApiController and additional IMyService interfaces), it works great but I want to add WebAPI specific attributes to this newly created Dynamic class, thus Web API framework can read them.
EDIT:
I want to explain detailed if someone want to know what I want actually.
public interface IMyService
{
IEnumerable<MyEntity> GetAll();
}
public class MyServiceImpl : IMyService
{
public IEnumerable<MyEntity> GetAll()
{
return new List<MyEntity>(); //TODO: Get from database!
}
}
public class MyServiceApiController : ApiController,IMyService
{
private readonly IMyService _myService;
public MyServiceApiController(IMyService myService)
{
_myService = myService;
}
public IEnumerable<MyEntity> GetAll()
{
return _myService.GetAll();
}
}
Think that I have a IMyService which is implemented by MyServiceImpl. And I want to make a Api controller to be able to use this service from web.
But as you see, api controller is just a proxy for real service. So, why I should write it? I can dynamically create it using castle windsor.
This is my idea and almost done it in my new project (https://github.com/hikalkan/aspnetboilerplate). But what if I need to add some attribute (such as Authorize) to GetAll method of the api controller. I cant directly add since there is no such a class, it's castle dynamic proxy.
So, beside this problem. I want to know if it's possible to add a attribute to a method of a synamic proxy class.
See again that project
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/55
I also want to know how, so that I can define RoutePrefix on IService and Route on Action.
Fortunately, I finally know how to define custom attributes for proxy.
public class CustomProxyFactory : DefaultProxyFactory
{
#region Overrides of DefaultProxyFactory
protected override void CustomizeOptions(ProxyGenerationOptions options, IKernel kernel, ComponentModel model, object[] arguments)
{
var attributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new[] { typeof(string) }), new object[] { "CustomizeOptions" });
options.AdditionalAttributes.Add(attributeBuilder);
}
#endregion
}
/// <summary>
/// 用户信息服务
/// </summary>
[Description("IUserInfoService")]
public interface IUserInfoService
{
/// <summary>
/// 获取用户信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[Description("IUserInfoService.GetUserInfo")]
UserInfo GetUserInfo([Description("IUserInfoService.GetUserInfo name")] string name);
}
/// <summary>
/// 用户信息服务
/// </summary>
[Description("UserInfoService")]
public class UserInfoService : IUserInfoService
{
/// <summary>
/// 获取用户信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[Description("UserInfoService.GetUserInfo")]
public virtual UserInfo GetUserInfo([Description("UserInfoService.GetUserInfo name")] string name)
{
return new UserInfo { Name = name };
}
}
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
[TestFixture]
public class AttributeTests
{
/// <summary>
/// Reference to the Castle Windsor Container.
/// </summary>
public IWindsorContainer IocContainer { get; private set; }
[SetUp]
public void Initialize()
{
IocContainer = new WindsorContainer();
IocContainer.Kernel.ProxyFactory = new CustomProxyFactory();
IocContainer.Register(
Component.For<UserInfoService>()
.Proxy
.AdditionalInterfaces(typeof(IUserInfoService))
.LifestyleTransient()
);
}
/// <summary>
///
/// </summary>
[Test]
public void GetAttributeTest()
{
var userInfoService = IocContainer.Resolve<UserInfoService>();
Assert.IsNotNull(userInfoService);
var type = userInfoService.GetType();
Assert.IsTrue(type != typeof(UserInfoService));
var attribute = type.GetCustomAttribute<DescriptionAttribute>();
Assert.IsTrue(attribute != null);
Trace.WriteLine(attribute.Description);
var method = type.GetMethod("GetUserInfo");
attribute = method.GetCustomAttribute<DescriptionAttribute>();
Assert.IsTrue(attribute != null);
Trace.WriteLine(attribute.Description);
var parameter = method.GetParameters().First();
attribute = parameter.GetCustomAttribute<DescriptionAttribute>();
Assert.IsTrue(attribute != null);
Trace.WriteLine(attribute.Description);
}
}
#hikalkan I faced the same problem and I was looking for a solution as well. The best I could encounter was
How to add an attribute to a property at runtime
Proxy the controller (in my case a dynamic controller) with a new wrapper that set those attributes in the class itself and its methods..

Dependency Injection when I am constructing the object

I am creating a custom ActionResult for my controllers because I've noticed a lot of repeated code that could be made reusable. It looks something like this:
public ExtendedViewResult<T> : ActionResult
{
protected T Model { get; set; }
protected IModelExtender<T> Extender { get; set; }
public ExtendedActionResult(T model, IModelExtender<T> extender)
{
this.Model = model;
this.Extender = extender;
}
}
public class BaseController : Controller
{
public ExtendedViewResult<T> ExtendedView<T>(T model)
{
// I need to create the result here, but how?
var result = new ExtendedViewResult<T>(model, ???????);
return result;
}
}
The problem I am having is that I'm not sure how to construct my ExtendedViewResult object. Since the interface is generic I want to use Dependency Injection to get the proper object, but I'm not sure how to do that since I'm constructing the object myself.
I am using Ninject and Ninject.MVC3 and the default Nuget package creates a Bootstrapper class for me, and when I access the Bootstrapper.Kernel property I get the following warning:
Ninject.Web.Mvc.Bootstrapper.Kernel is obsolete. Do not use Ninject as Service Locator.
If I'm not supposed to access the kernel directly, then how can I change my code so that I can get the appropriate concrete class?
EDIT
Here is the ninject bootstrapper code. The only method I added is the GetInstance()
public static class NinjectMVC3
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
// I ADDED THIS CODE, EVERYTHING ELSE IS AUTO-GENERATED
// BY THE NUGET PACKAGE
public static T GetInstance<T>()
{
return bootstrapper.Kernel.Get<T>();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}
Sorry this will be dry on actual code - I've not used ninject much, but other DI containers have this solution, and I'm sure ninject will have this construct as well.
The issue is that you are constructing the object itself. When you're really using a DI container and following IoC, anytime you see the keyword new should be a red flag - and using the container as a service locator is a yellow one.
So how do we get rid of the 'new', since you need a new object? The answer is to have your BaseController take a dependency on a factory that can create an ExtendedViewResult. In Autofac (my container of choice), that would be as simple as having a Func<ExtendedViewResult> injected. I would be surprised if Ninject doesn't have the same. In fact, looks like it does - this ninject wiki page points to this blog post on Ninject.Extensions.Factory.
So that means your code for the Controller could look like this:
public class ConcreteController : BaseController
{
private Func<Foo,ExtendedViewResult<Foo>> _factory;
public BaseController(Func<Foo,ExtendedViewResult<Foo>> factory)
{
_factory = factory;
}
public ExtendedViewResult<Foo> Method(Foo model)
{
var result = _factory(model);
return result;
}
}
If you REALLY want to have a generic method do the creation in your base class, then you will probably need to go the explicit factory interface route from the blog post linked above. With this style code though, you would not need it in most cases, and your controllers explicitly declare the dependencies they need.
You should be using an abstract factory anytime your objects want to create other objects. The abstract factory itself can injected. I've asked a similar question here: Abstract factories when using dependency injection frameworks
It really shouldn't make much of a difference that your factory is generic though.

Wizard in asp.NET MVC3 using a static object

I'm trying to make a wizard in MVC3 using Entity Framework. It needs to keep the state of an object (an article in this case) across a couple of steps.
I have a static variable in my controller that instantiates a new Article. In the different Actions I use TryUpdateModel to map the form to the static variable. The problem is, it seems that TryUpdateModel() updates the database as well. I need TryUpdateModel to do the automatic mapping, and update the static _article variable, but I don't want it to persist to the database until the last step!
N.B: I know there are a lot of possible solutions for creating a wizard in MVC, but I'd like to know what to do to make this way work, so please no alternatives for an MVC wizard-pattern.
Thanks.
namespace website.Controllers
{
public class ArticlesController : BaseController
{
// private static variable to hold the chosen article in the wizard
private static articles _article = new articles();
/// <summary>
/// Index page shows a list of articles in a webgrid
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
List<articles> _articles = Data.getArticles();
return View(_articles);
}
/// <summary>
/// First page of the article wizard
/// </summary>
/// <returns></returns>
public ActionResult BasicDetails(string id, string nextButton)
{
// back or next doesn't matter - store form values
if (_article != null) TryUpdateModel(_article);
if (nextButton != null)
{
return RedirectToAction("ArticleGroup");
}
else
{
_article = Data.GetArticleById(id);
return View(_article);
}
}
/// <summary>
/// Second page of the article wizard
/// </summary>
/// <returns></returns>
public ActionResult ArticleGroup(string nextButton, string backButton)
{
TryUpdateModel(_article);
if (backButton != null)
return RedirectToAction("BasicDetails");
else if (nextButton != null)
{
return RedirectToAction("Price");
}
else
{
return View(_article);
}
}
/// <summary>
/// Third page of the article wizard
/// </summary>
/// <returns></returns>
public ActionResult Price(string nextButton, string backButton)
{
TryUpdateModel(_article);
if (backButton != null)
{
return RedirectToAction("ArticleGroup");
}
else if (nextButton != null)
return RedirectToAction("LinkedClubs");
else
{
return View(_article);
}
}
/// <summary>
/// Last page of the article wizard
/// </summary>
/// <returns></returns>
public ActionResult LinkedClubs(string backButton)
{
if (backButton != null)
return RedirectToAction("Price");
else
return View(_article);
}
}
}
Rather than using a static variable to hold your state information (that is a critical error btw) you should pass a state bag holding the information that you need in between pages.
Usually data entities (entities mapped to database) and viewmodel entities (entities with that user works) used separately. When user posted data after some step - you make TryUpdateModel() to session object (specific for user, not for all application as static variable).
At last step you call business logic method UpdateModel(viewmodel), that update all columns by id of viewmodel, using all filled properties.

How can I do this? I need to call a Service Class but I need to pass in parameters

I need to call something in my application start to start my quartz.net scheduler.
The problem is that I need to pass in a repository into my service layer that normally is done with ninject and dependency injection.
//global.aspx
public class MvcApplication : System.Web.HttpApplication
{
private readonly IScheduledRemindersService scheduledRemindersService;
public MvcApplication(IScheduledRemindersService
scheduledRemindersService)
{
this.scheduledRemindersService = scheduledRemindersService;
}
protected void Application_Start()
{
//other default stuff here like mvc routers.
scheduledRemindersService.RemindersSchedule();
}
}
private readonly IReminderRepo reminderRepo;
public ScheduledRemindersService(IReminderRepo reminderRepo)
{
this.reminderRepo = reminderRepo;
}
private readonly IReminderRepo reminderRepo;
public ScheduledRemindersService(IReminderRepo reminderRepo)
{
this.reminderRepo = reminderRepo;
}
I have NHibernate set to so when It seems IReminderRepo it shoudl bind it and in IReminderRepo I have
private readonly ISession session;
public ReminderRepo(ISession session)
{
this.session = session;
}
This will also get automatically binded through nhibernate.
This won't work though as the global.aspx only allows no argument constructors.
So how can inject the right classes to these interfaces? Especially the nhibernate session that is the most important thing I need.
Edit
public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NhibernateSessionFactory();
return sessionFactory.GetSessionFactory();
}
}
public class NhibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
// in the global.aspx
protected IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new NhibernateModule(),
new ServiceModule(),
new RepoModule(),
};
return new StandardKernel(modules);
}
// in RepoModule()
Bind<IReminderRepo>().To<ReminderRepo>();
// in serviceModule
Bind<IScheduledRemindersService>().To<ScheduledRemindersService>()
We use a method like this in our Global.asax.cs file for exactly this purpose (it gets called from Application_Start:
private static void SetupScheduling(IKernel kernel)
{
var scheduler = SchedulerUtil.Scheduler;
scheduler.JobFactory = kernel.Get<IJobFactory>();
scheduler.Start();
}
And we have IJobFactory bound to the following class:
public class QuartzJobFactory : IJobFactory
{
private readonly IObjectFactory<IJob> _jobFactory;
private readonly LogService _logService;
public QuartzJobFactory(IObjectFactory<IJob> jobFactory,
LogService logService)
{
_jobFactory = jobFactory;
_logService = logService;
}
/// <summary>
/// Called by the scheduler at the time of the trigger firing, in order to
/// produce a <see cref="T:Quartz.IJob"/> instance on which to call Execute.
/// </summary>
/// <remarks>
/// <p>It should be extremely rare for this method to throw an exception -
/// basically only the the case where there is no way at all to instantiate
/// and prepare the Job for execution. When the exception is thrown, the
/// Scheduler will move all triggers associated with the Job into the
/// <see cref="F:Quartz.TriggerState.Error"/> state, which will require human
/// intervention (e.g. an application restart after fixing whatever
/// configuration problem led to the issue wih instantiating the Job.
/// </p>
/// </remarks>
/// <param name="bundle">The TriggerFiredBundle from which the <see cref="T:Quartz.JobDetail"/>
/// and other info relating to the trigger firing can be obtained.
/// </param><throws>SchedulerException if there is a problem instantiating the Job. </throws>
/// <returns>
/// the newly instantiated Job
/// </returns>
public IJob NewJob(TriggerFiredBundle bundle)
{
Type jobType;
try
{
Require.ThatArgument(bundle != null);
Require.ThatArgument(bundle.JobDetail != null);
jobType = bundle.JobDetail.JobType;
}
catch (Exception e)
{
// This shouldn't ever happen, but if it does I want to know about it.
_logService.LogCritical(() => e.ToString());
throw;
}
try
{
return _jobFactory.GetObject(jobType);
}
catch (Exception e)
{
_logService.LogCritical(() => "An exception was thrown while creating job of type {0}: {1}"
.With(jobType, e));
throw;
}
}
}
And IObjectFactory is a simple interface that just abstracts away the Kernel so we're not depending on Ninject everywhere:
/// <summary>
/// Similar to IFactory, but this factory produces types based on a dynamic
/// <see cref="Type"/> object. If the given Type object is not of the given
/// "T" type, an exception will be thrown.
/// </summary>
/// <typeparam name="T">A parent-level type representing what sort of values
/// are expected. If the type could be anything, try using <see cref="object"/>
/// </typeparam>
public interface IObjectFactory<out T>
{
T GetObject(Type type);
}
IObjectFactory is then bound to a class like this:
/// <summary>
/// This implementation of the generic <see cref="IFactory{T}"/> and
/// <see cref="IObjectFactory{T}"/> classes uses Ninject to supply instances of
/// the given type. It should not be used explicitly, but will rather be used
/// by the DI framework itself, to provide instances to services that depend on
/// IFactory objects.
/// This implementation takes the injection context as a constructor argument, so that
/// it can reuse elements of the context when it is asked to supply an instance
/// of a type.
/// In order for this to work, you will need to define bindings from <see cref="IFactory{T}"/>
/// and <see cref="IObjectFactory{T}"/> to this class, as well as a binding from
/// <see cref="IContext"/> to a method or factory that returns the current binding
/// context.
/// </summary>
/// <typeparam name="T">The Type of the service to be produced by the Get method.</typeparam>
public class InjectionFactory<T> : IFactory<T>, IObjectFactory<T>
{
private readonly IKernel _kernel;
private readonly IParameter[] _contextParameters;
/// <summary>
/// Constructs an InjectionFactory
/// </summary>
/// <param name="injectionContext">The context in which this injection is taking place.</param>
public InjectionFactory(IContext injectionContext)
{
_contextParameters = injectionContext.Parameters
.Where(p => p.ShouldInherit).ToArray();
_kernel = injectionContext.Kernel;
}
public T Get()
{
try
{
return _kernel.Get<T>(_contextParameters.ToArray());
}
catch (Exception e)
{
throw e.Wrap(() => "An error occurred while attempting to instantiate an object of type <{0}>".With(typeof(T)));
}
}
public T GetObject(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (!typeof (T).IsAssignableFrom(type))
{
throw new InvalidCastException(type.FullName + " is not a child type of " + typeof (T).FullName);
}
try
{
return (T)_kernel.Get(type, _contextParameters);
}
catch (Exception e)
{
throw e.Wrap(() => "An error occurred while attempting to instantiate an object of type <{0}>".With(typeof(T)));
}
}
}
... using a binding that looks like this:
Bind(typeof (IObjectFactory<>)).To(typeof (InjectionFactory<>));
// Injection factories ask for the injection context.
Bind(typeof (IContext)).ToMethod(c => c.Request.ParentContext);
So the overall effect is that we use the Ninject kernel to create the IJobFactory, which uses constructor injection to take an IObjectFactory<IJob>, which is invoked to produce any IJobs that Quartz requires. Those job classes can therefore use constructor-based injection, and Ninject is indirectly instantiating them.
i don't think you have understood IoC very well. When you say the ISession will get auto binded through NHibernate - what are you thinking happens? NHibernate won't manage that for you. Session lifestyle management is your domain.
I don't think there is enough code to really help you. the service as well as the repository would need to be managed by your IoC to be able to inject one into the other - unless you have a direct reference to the IoC - which is not recommended.
You should get the instance of IScheduledRemindersService from your IoC container. The container should take charge of injecting all of the dependencies for you as it creates/resolves the instance.
I'm not familiar with NInject so I can't tell you how it should be done, but you should do something along the lines of:
protected void Application_Start()
{
// 1- register IoC container
// 2- resolve instance of IScheduledRemindersService
// 3- invoke RemindersService() method on instance
}

Resources