MVC project No parameterless constructor defined for this object - asp.net-mvc

im getting this error. Im newbie on MVC .
Can you help me please.I found somethings but i didnt understand what i will do. Sorry for my english.
I have 4 projects in a solution
.Admin
.UI
.Core
.Data
I have a problem with admin side.
Im trying to LoginFilter in admin page. When i run the project the page forwarding to /Account/Login page but its giving this error.
Error Page:
No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +206
System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
System.Activator.CreateInstance(Type type) +11
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55
[InvalidOperationException: An error occurred when trying to create a controller of type 'WebHaber.Admin.Controllers.AccountController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +178
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +76
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +88
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +194
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1098.0
AccountController.cs
using WebHaber.Core.Infrastructure;
using WebHaber.Data.Model;
namespace WebHaber.Admin.Controllers
{
public class AccountController : Controller
{
#region Kullanıcı
private readonly IKullaniciRepository _kullaniciRepository;
public AccountController(IKullaniciRepository kullaniciRepository)
{
_kullaniciRepository = kullaniciRepository;
}
#endregion
// GET: Account
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Kullanici kullanici)
{
var KullaniciVarmi = _kullaniciRepository.GetMany(x => x.Email == kullanici.Email && x.Sifre == kullanici.Sifre && x.Aktif == true).SingleOrDefault();
if (KullaniciVarmi != null)
{
if (KullaniciVarmi.Rol.RolAdi == "Admin")
{
Session["KullaniciEmail"] = KullaniciVarmi.Email;
return RedirectToAction("Index", "Home");
}
ViewBag.Mesaj = "Yetkisiz Kullanıcı";
return View();
}
ViewBag.Mesaj = "Kullanıcı Bulunamadı";
return View();
}
LoginFilter.cs
namespace WebHaber.Admin.CustomFilter
{
public class LoginFilter : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
HttpContextWrapper wrapper = new HttpContextWrapper(HttpContext.Current);
var SessionControl = context.HttpContext.Session["KullaniciEmail"];
if (SessionControl == null)
{
context.Result = new RedirectToRouteResult(
new RouteValueDictionary { { "Controller", "Account" }, { "action", "Login" } });
}
}
public void OnActionExecuting(ActionExecutingContext context)
{}
BootStrapper.cs
using Autofac;
using Autofac.Integration.Mvc;
using WebHaber.Core.Infrastructure;
using WebHaber.Core.Repository;
using WebHaber.Data.DataContext;
namespace WebHaber.Admin.Class
{
public class BootStrapper
{
//Boot aşamasında çalışacak.
public static void RunConfig()
{
BuilAutoFac();
}
private static void BuilAutoFac()
{
var builder = new ContainerBuilder();
builder.RegisterType<HaberRepository>().As<IHaberRepository>();
builder.RegisterType<ResimRepository>().As<IResimRepository>();
builder.RegisterType<KullaniciRepository>().As<IKullaniciRepository>();
builder.RegisterType<RolRepository>().As<IRolRepository>();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
Global.asax
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BootStrapper.RunConfig();
}
}
KullaniciRepository.cs
namespace WebHaber.Core.Repository
{
public class KullaniciRepository : IKullaniciRepository
{
private readonly HaberContext _context = new HaberContext();
public IEnumerable<Kullanici> GetAll()
{
//Tüm haberler dönecek
return _context.Kullanici.Select(x => x);
}
public Kullanici GetByID(int id)
{
return _context.Kullanici.FirstOrDefault(x => x.ID == id);
}
public Kullanici Get(Expression<Func<Kullanici, bool>> expression)
{
return _context.Kullanici.FirstOrDefault(expression);
}
public IQueryable<Kullanici> GetMany(Expression<Func<Kullanici, bool>> expression)
{
return _context.Kullanici.Where(expression);
}
public void Insert(Kullanici obj)
{
_context.Kullanici.Add(obj);
}
public void Update(Kullanici obj)
{
_context.Kullanici.AddOrUpdate();
}
public void Delete(int id)
{
var kullanici = GetByID(id);
if (kullanici!= null)
{
_context.Kullanici.Remove(kullanici);
}
}
public int Count()
{
return _context.Kullanici.Count();
}
public void Save()
{
_context.SaveChanges();
}
}
}
IKullaniciRepository.cs
namespace WebHaber.Core.Infrastructure
{
public interface IKullaniciRepository : IRepository<Kullanici>
{
}
}
IRepository.cs
namespace WebHaber.Core.Infrastructure
{
public interface IRepository<T> where T: class
{
IEnumerable<T> GetAll();
T GetByID(int id);
T Get(Expression<Func<T, bool>> expression);
IQueryable<T> GetMany(Expression<Func<T, bool>> expression);
void Insert(T obj);
void Update(T obj);
void Delete(int id);
int Count();
void Save();
}
}
Kullanici.cs model
namespace WebHaber.Data.Model
{
[Table("Kullanici")]
public class Kullanici
{
public int ID { get; set; }
[Display(Name = "Ad Soyad")]
[MaxLength(150, ErrorMessage = "150 karakterden fazla girildi.")]
[Required]
public string AdSoyad { get; set; }
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[Required]
public string Email { get; set; }
public string KullaniciAdi { get; set; }
[Display(Name = "Şifre")]
[DataType(DataType.Password)]
[Required]
public string Sifre { get; set; }
..............
..............
.............

The issue is pretty straightforward — An error occurred when trying to create a controller of type 'WebHaber.Admin.Controllers.AccountController'. Make sure that the controller has a parameterless public constructor.
You're trying to use Autofac to inject IKullaniciRepository service into the AccountController but the compiler couldn't find one although you've the declared the service registration at BootStrapper.cs
Therefore it's likely that BootStrapper.cs's RunConfig never get invoked. Just place a call (e.g. BootStrapper.RunConfig()) to Application_Start() method in Global.asax and you're fine.

#Zephyr thank you for help.
I added new global.asax file.
Because my Application_Start() was not firing.
In global.asax
Old one :
public class MvcApplication : System.Web.HttpApplication
new one: `
public class Global : System.Web.HttpApplication`

Related

Changing the type of action parameter at runtime depending on current user in aspnet webapi

How to alter the TViewModel from within a action filter or a model binder?
[HasPriviliege]
public IHttpActionResult Get(long id)
{
var entity = AutoMapper.Mapper.Map<TViewModel, TEntity>(model);
repo.Update(id, entity);
repo.Save();
return Ok(model);
}
[HasPriviliege]
public IHttpActionResult Edit(long id, TViewModel model)
{
var entity = AutoMapper.Mapper.Map<TViewModel, TEntity>(model);
repo.Update(id, entity);
repo.Save();
return Ok(model);
}
the filter should be
public class HasPriviliege:ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if(getPrivileges()=="doctor"){
//the TViewModel(view model type to bind to) should be
// DoctorPatientViewModel should be;
}else{
//the TViewModel(view model type to bind to) should be
//ExaminationPatientViewModel
}
//base.OnActionExecuting(actionContext);
}
}
or alternativaly, the model binder
public class IPrivilegeableModelBinder: IModelBinder
{
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
//return (hasPriviliege()?DoctorPatientViewModel:ExaminationPatientViewModel) ;
}
}
Rather than write an over-bloated comment, I'll post my suggestion on how we accomplished something similar to this using a generic controller.
Controller factory:
public class ControllerFactory : IControllerFactory
{
public IController CreateController(RequestContext requestContext, string controllerName)
{
Type controllerType = typeof(GenericController<>);
Type genericType = controllerType.MakeGenericType(GetPrivilegeType());
ConstructorInfo ctor = genericType.GetConstructor(new Type[]{});
return (IController)ctor.Invoke(new object[] { });
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
...
return SessionStateBehavior.ReadOnly;
}
public void ReleaseController(IController controller)
{
if (controller is IDisposable)
{
((IDisposable)controller).Dispose();
}
}
private string GetPrivilegeType()
{
if (getPrivileges() == "doctor") {
return typeof(DoctorPatientViewModel);
} else {
return typeof(ExaminationPatientViewModel);
}
}
}
Register it like this:
ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
...and finally what your controller might look like
public class GenericController<TViewModel> // TViewModel will be the privilege type from the factory
where TViewModel : IPrivilege
{
[HasPriviliege]
public IHttpActionResult Edit(long id, TViewModel model)
{
var entity = AutoMapper.Mapper.Map<TViewModel, TEntity>(model);
repo.Update(id, entity);
repo.Save();
return Ok(model);
}
}
That's the most basic example to get a generic controller working for mvc which might go some way to what you're trying to accomplish.

No matching bindings are available, and the type is not self-bindable.

What's wrong with my binding?
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IBaseRepository<User>>().To<UserRepository>();
}
My IBaseRepository
public interface IBaseRepository<TEntity> where TEntity : class
{
void Commit();
void Delete(TEntity entity);
void Delete(object id);
void Dispose();
IQueryable<TEntity> GetAll();
IQueryable<TEntity> GetAll(object filter);
TEntity GetById(object id);
TEntity GetFullObject(object id);
IQueryable<TEntity> GetPaged(int top = 20, int skip = 0, object orderBy = null, object filter = null);
void Insert(TEntity entity);
void Update(TEntity entity);
}
And my UserRepository
public class UserRepository : BaseRepository<User>
{
public UserRepository(DataContext context) : base(context)
{
if(context == null)
throw new ArgumentNullException();
}
}
This is the error I recive
Error activating IBaseRepository{Role}
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IBaseRepository{Role} into parameter roles of constructor of type UsersController
1) Request for UsersController
Well your exception message clearly states that the binding for IBaseRepository<Role> is missing. Role not User.
So adding
kernel.Bind<IBaseRepository<Role>>().To<RoleRepository>();
should help! ;-)

Override ItemController in Custom Module in Orchard

What do I want?
I'm trying to override the Display method of the ItemController (Orchard.Core.Contents.Controllers.ItemController), so I can change the output based on the Accept Header.
If the header is "application/xml" I want to return xml
If the header is "application/json" I want to return json
Else return html ( like the default Display method)
What have I done?
I've made a copy of the ItemController and have placed it in the Controller folder of my custom Module. Also added the OrchardSuppressDependency Attribute above the class.
[OrchardSuppressDependency("Orchard.Core.Contents.Controllers.ItemController")]
[Themed]
public class ItemController : Controller
{
private readonly IContentManager _contentManager;
public ItemController(IContentManager contentManager, IShapeFactory shapeFactory, IOrchardServices services)
{
_contentManager = contentManager;
Shape = shapeFactory;
Services = services;
T = NullLocalizer.Instance;
}
dynamic Shape { get; set; }
public IOrchardServices Services { get; private set; }
public Localizer T { get; set; }
// /Contents/Item/Display/72
public ActionResult Display(int id)
{
var contentItem = _contentManager.Get(id, VersionOptions.Published);
if (contentItem == null)
return HttpNotFound();
if (!Services.Authorizer.Authorize(Permissions.ViewContent, contentItem, T("Cannot view content")))
{
return new HttpUnauthorizedResult();
}
//#Todo change output
dynamic model = _contentManager.BuildDisplay(contentItem);
return View((object)model);
}
Result
An error is thrown in ShellRoute.cs Displaying
{"The controller for path '/OrchardLocal/products/product-2' was not found or does not implement IController."}
StackTrace
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at Orchard.Mvc.OrchardControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) in XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\src\Orchard\Mvc\OrchardControllerFactory.cs:line 76
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at Orchard.Mvc.Routes.ShellRoute.HttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) in XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\src\Orchard\Mvc\Routes\ShellRoute.cs:line 148
Have I overlooked something?
Or is this the wrong approach?

ASP.NET MVC - setting custom IControllerFactory has no effect

I really dont understand what I'm doing wrong here - for some reason the IControllerFactory i register is not being used, and I end up with a System.ArgumentException:
Type 'Company.WebApi.Controllers.AController' does not have a default
constructor
at System.Linq.Expressions.Expression.New(Type type) at
System.Web.Http.Internal.TypeActivator.Create[TBase](Type
instanceType) at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage
request, Type controllerType, Func`1& activator) at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage
request, HttpControllerDescriptor controllerDescriptor, Type
controllerType)
In Global.asax.cs
protected void Application_Start()
{
//DI-setup
var container = new WindsorContainer().Install(new WebWindsorInstaller());
//set custom controller factory
var controllerFactory = container.Resolve<IControllerFactory>();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
//register cors
container.Resolve<ICorsConfig>().RegisterCors(GlobalConfiguration.Configuration);
//routes
RegisterRoutes(RouteTable.Routes);
}
My IControllerFactory is based on this article http://keyvan.io/custom-controller-factory-in-asp-net-mvc and is implemented as following
public class ControllerFactory : IControllerFactory
{
private readonly IWindsorContainer _container;
public ControllerFactory(IWindsorContainer container)
{
if(container == null)
throw new ArgumentNullException("container");
_container = container;
}
public IController CreateController(RequestContext requestContext, string controllerName)
{
if (string.IsNullOrEmpty(controllerName))
throw new ArgumentNullException("controllerName");
var componentName = GetComponentNameFromControllerName(controllerName);
return _container.Resolve<IController>(componentName);
}
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
throw new NotImplementedException();
}
public void ReleaseController(IController controller)
{
_container.Release(controller);
}
static string GetComponentNameFromControllerName(string controllerName)
{
var controllerNamespace = typeof (CrudController<>).Namespace;
return string.Format("{0}.{1}Controller", controllerNamespace, controllerName);
}
}
I've been staring at this for hours, and really can't see why this isn't working. When debugging the ControllerFactory is never hit in any method except the constructor. Anyone see whats wrong or missing here?
(Setting ASP.NET MVC ControllerFactory has no effect does not answer my question)
Edit 1 - Controller
public class AController : CrudController<AModel>
{
public AController(IAHandler aHandler) : base(aHandler)
{
...
}
[HttpGet]
public HttpResponseMessage GetByUser(string aId)
{
...
}
}
public abstract class CrudController<T> : ApiController
where T : IModel, new()
{
protected CrudController(ICrudHandler<T> handler)
{
...
}
[HttpGet]
public HttpResponseMessage Get(string id)
{
...
}
[HttpPost]
public HttpResponseMessage Post(T input)
{
...
}
[HttpPut]
public HttpResponseMessage Put(T input)
{
...
}
}
Edit 2 - Installer
public sealed class WebWindsorInstaller : IWindsorInstaller
{
private bool _installComplete;
public void Install(IWindsorContainer container, IConfigurationStore store)
{
if(_installComplete)
return;
//register self for reuse
container.Register(Component.For<IWindsorInstaller>().Instance(this));
//controller factory
container.Register(
Component.For<IControllerFactory>().ImplementedBy<ControllerFactory>().LifeStyle.Singleton);
//Handlers
container.Register(
Classes.FromAssemblyContaining<AHandler>().InSameNamespaceAs<AHandler>().WithService.
DefaultInterfaces());
//Models
container.Register(
Classes.FromAssemblyContaining<AModel>().InSameNamespaceAs<AModel>().WithService.Self());
//DI
container.Register(Component.For<IWindsorContainer>().Instance(container));
container.Register(Component.For<IDependencyResolver>().ImplementedBy<WindsorDependencyResolver>());
//Controllers
container.Register(Classes
.FromAssemblyContaining<AController>()
.BasedOn<IHttpController>()
.LifestyleScoped());
//repositories
container.Register(
Classes.FromAssemblyContaining<ARepository>().InSameNamespaceAs<ARepository>().WithService.
DefaultInterfaces());
//cors
container.Register(Component.For<ICorsConfig>().ImplementedBy<CorsConfig>());
_installComplete = true;
}
}
From the error messages in your question it looks like you actually want to register WebAPI controllers. It's important to note that these are not the same as MVC controllers, and do not use the same controller factory (which you are trying to use).
See Mark Seeman's post Dependency Injection in ASP.NET Web API with Castle Windsor for details of how to do this for Web API controllers.

Ninject + "Error loading Ninject component ICache"

I've just installed the new Ninject.MVC3 from NuGet and trying to make it work in my asp.net mvc 3 app, however I get this weird error now and then when surfing my site:
[InvalidOperationException: Error loading Ninject component ICache
No such component has been registered in the kernel's component container.
Suggestions:
1) If you have created a custom subclass for KernelBase, ensure that you have properly
implemented the AddComponents() method.
2) Ensure that you have not removed the component from the container via a call to RemoveAll().
3) Ensure you have not accidentally created more than one kernel.
]
Ninject.Components.ComponentContainer.Get(Type component) in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\Components\ComponentContainer.cs:146
Ninject.Components.ComponentContainer.Get() in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\Components\ComponentContainer.cs:102
Ninject.KernelBase.CreateContext(IRequest request, IBinding binding) in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\KernelBase.cs:540
Ninject.<>c__DisplayClassa.<Resolve>b__6(IBinding binding) in d:\BuildAgent-01\work\b68efe9aafe8875e\src\Ninject\KernelBase.cs:375
System.Linq.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x) +20
System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
System.Linq.Enumerable.SingleOrDefault(IEnumerable`1 source) +4178557
Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:56
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +51
[InvalidOperationException: An error occurred when trying to create a controller of type 'MyApp.Controllers.NewsController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +196
System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862580
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
And my code is:
// AppStart_NinjectMVC3.cs
using System.Web.Mvc;
using Ninject.Modules;
[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.AppStart_NinjectMVC3), "Start")]
namespace MyApp
{
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
public static class AppStart_NinjectMVC3
{
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpApplicationModule));
}
}
}
// NinjectHttpApplicationModule.cs
using MyApp.Data;
using NHibernate;
namespace MyApp
{
using System;
using System.Web;
using Ninject;
using Ninject.Web.Mvc;
public sealed class NinjectHttpApplicationModule : IHttpModule, IDisposable
{
#region Ninject Mvc3 extension bootstrapper (Do not touch this code)
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
private static bool initialized;
private static bool kernelDisposed;
/// <summary>
/// Initializes a module and prepares it to handle requests.
/// Do not change this method!
/// </summary>
/// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
public void Init(HttpApplication context)
{
lock (bootstrapper)
{
if (initialized)
{
return;
}
initialized = true;
bootstrapper.Initialize(CreateKernel);
}
}
/// <summary>
/// Disposes the <see cref="T:System.Web.HttpApplication"/> instance.
/// Do not change this method!
/// </summary>
public void Dispose()
{
lock (bootstrapper)
{
if (kernelDisposed)
{
return;
}
kernelDisposed = true;
bootstrapper.ShutDown();
}
}
#endregion
/// <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)
{
kernel.Bind<ISession>().ToMethod(x => kernel.Get<SessionFactoryBuilder>().CreateFactory().OpenSession()).InRequestScope();
kernel.Bind<ITransaction>().ToMethod(x => kernel.Get<ISession>().BeginTransaction()).InRequestScope();
kernel.Bind(typeof(IRepositoryBase<>)).To(typeof(RepositoryBase<>));
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
}
}
}
Most of the code is the default one you get when installing by NuGet.. the only thing I've done is to add some bindings to the RegisterServices()
Any suggestions?
Fixed in 2.2.1.0
See http://www.planetgeek.ch/2011/03/01/ninject-2-2-1-0-and-ninject-mvc3-2-2-1-0-released/ for more information.
Looks like its a bug according to this thread, and that they are working on a fix...
Like previously mentioned it does look like a bug.
One option is to simply implement a singleton extension method yourself:
public static class NinjectSingletonExtension
{
public static CustomSingletonKernelModel<T> SingletonBind<T>(this IKernel i_KernelInstance)
{
return new CustomSingletonKernelModel<T>(i_KernelInstance);
}
}
public class CustomSingletonKernelModel<T>
{
private const string k_ConstantInjectionName = "Implementation";
private readonly IKernel _kernel;
private static object padlock = new Object();
private T _concreteInstance;
public CustomSingletonKernelModel(IKernel i_KernelInstance)
{
this._kernel = i_KernelInstance;
}
public IBindingInNamedWithOrOnSyntax<T> To<TImplement>(TImplement i_Constant = null) where TImplement : class, T
{
_kernel.Bind<T>().To<TImplement>().Named(k_ConstantInjectionName);
var toReturn =
_kernel.Bind<T>().ToMethod(x =>
{
if (i_Constant != null)
{
return i_Constant;
}
if (_concreteInstance == null)
{
lock (padlock)
{
if (_concreteInstance == null)
{
_concreteInstance = _kernel.Get<T>(k_ConstantInjectionName);
}
}
}
return _concreteInstance;
}).When(x => true);
return toReturn;
}
}
And then simply use:
i_Kernel.SingletonBind<T>().To<TImplement>();
Rather then
i_Kernel.Bind<T>().To<TImplement>().InSingletonScope();

Resources