I'm trying to inject a repository to a custom membership provider with ninject in MVC 3.
In MembershipProvider I have tried the following:
[Inject]
public ICustomerRepository _customerRepository{ get; set; }
And
[Inject]
public TUMembershipProvider(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
In my ninject module i tried the following:
Bind<MembershipProvider>().ToConstant(Membership.Provider);
None of the above works.
When i use(in global.asa)
kernel.Inject(Membership.Provider);
together with
[Inject]
public ICustomerRepository _customerRepository{ get; set; }
it works, but i have no life cycle management and this will cause a "ISession is open" error from NHibernate, because the ISession is InRequestScope and the repository is not.
You could use the approach #Remo Gloor outlines in his blog post on provider injection. It involves 3 steps:
Add [Inject]s to any properties on your provider you need injected (although the pattern he shows -- creating a very simple class whose only function is to be a receptable for property injection and forwards any requests to a real class implemented using constructor injection -- is well worth following)
public class MyMembershipProvider : SqlMembershipProvider
{
[Inject]
public SpecialUserProvider SpecialUserProvider { get;set;}
...
Create an initializer wrapper that implements IHttpModule which pulls the provider in, triggering its creation:-
public class ProviderInitializationHttpModule : IHttpModule
{
public ProviderInitializationHttpModule(MembershipProvider membershipProvider)
{
}
...
Register the IHttpModule in your RegisterServices :-
kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();
there is no 4; Ninject does the rest - bootstrapping all registered IHttpModules including the one you added) during the startup sequence.
(Don't forget to read the comments on the blog post re lifetimes etc.)
Finally, if you're looking for something completely braindead direct that solves it neatly, try this #Remo Gloor answer instead
PS a great writeup on the whole mess is Provider is not a Pattern by #Mark Seemann. (and the oboligatory plug for his excellent book:- Dependency injection in .NET which will have you figuring this stuff out comfortably from first principles)
i had this problem
a custom membership, role and profile provider in another project from MVC using repository, when ever i call the provider the injected repository was null.
tried to call kernel.Inject(Membership.Provider); in the NinjectWebCommon method registerServices(IKernel kernel) but got the exception
The result is always null, because asp.net has it's own static property for membership.which is membership.provider. and this instance is not part of instance ninject management.
so use on PostApplicationStartMethod
here is the soloution by cipto add to NinjectWebCommon the attrbute and method :
[assembly: WebActivator.PreApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "RegisterMembership")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebApp.App_Start.NinjectWebCommon), "Stop")]
public static void RegisterMembership()
{
bootstrapper.Kernel.Inject(Membership.Provider);
}
The problem is that the whole Membership infrastructure is a "native" .NET code (System.Web.Security) that does not know about MVC and about the DI container used by MVC.
The static call to Membership.Provider returns the membership provider based on the configuration, however, the specified provider type is instantiated with a simple Activator.CreateInstance call. Hence, the dependency injection has no chance to kick in and set your repository dependency on the result. If you explicitly setup the returned instance with Ninject it can work, because you explicitly gave Ninject the object to set the dependencies. Even in this case it can only work with property injection and not with constructor injection, because the instance is created by the membership configuration previously.
To summarize: you cannot easily inject dependencies into the membership provider because it is not resolved from a dependency injection container.
I think you have 2 possibilities:
You create a repository in the custom membership provider directly or you access it by some other means on demand (where the web context is already present).
You go one level higher and check the components that would use your membership provider and you try change there (to use a membership provider resolved from your DI container instead of the uninitialized Memership.Provider). If this "higher component" is the forms authentication, then this article might be of help (using dependency injection with IFormsAuthentication and IMembershipService): http://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx
Did you try resolving your repository "manually", like in this answer:
Ninject : Resolving an object by type _and_ registration name/identifier
?
Related
I am creating one demo application to learn how to use repository pattern for performing Insert operation.I am using Nop Commerce**(http://www.nopcommerce.com) **code for repository pattern
Error:No parameterless constructor defined for this object
I have seen this link:MVC: No parameterless constructor defined for this object
This is my Structure:
My Repository interface:
public partial interface IRepository<T>
{
void Insert(T entity);
}
My Service Layer:
public partial interface IEmployeeService
{
void InsertCategory(EmployeeMaster employeeMaster);
}
My Class which will implement that interface(service):
public partial class EmployeeService : IEmployeeService
{
#region Fields
private readonly IRepository<EmployeeMaster> _employeeMasterRepository;
#endregion
#region Ctor
public EmployeeService
(
IRepository<EmployeeMaster> employeeMasterRepository
)
{
this._employeeMasterRepository = employeeMasterRepository;
}
#endregion
public virtual void InsertCategory(EmployeeMaster employeeMaster)
{
if (employeeMaster == null)
throw new ArgumentNullException("employeeMaster");
_employeeMasterRepository.Insert(employeeMaster);
}
This is my controller:
public class HomeController : Controller
{
#region Fields
private readonly IEmployeeService _employeeService;
#endregion
#region Constructors
public HomeController
(
IEmployeeService employeeService
)
{
this._employeeService = employeeService;
}
#endregion
Getting Error:No parameterless constructor defined for this object
I have studied regarding this error and all the sources are saying that use Dependency injection to solve this error.
Can anybody guide me how to use dependency injection to solve this error??
Maybe you're taking as a sample a project that is too complex for you at this moment. Nopcommerce is a big and full featured product that has a lot of elements, so it easy to get lost. Not the best sample to learn how the repository pattern works, but I certainly recommend you to check it again once you have the basic concepts clear to see them used in a real scenario.
NopCommerce uses Autofac for dependency injection, a very popular IoC container. You can look for a class called DependencyRegistrar in the project Nop.Web.Framework to see how it is used, if you're curious about it. You can get more examples on how to use dependency injection with Autofac in their repository and their getting started guide.
My recommendation is to look for an easier to follow example. For starters, any of the popular IoC containers will be OK until you have your own criteria to choose one. For instance you can follow the Autofac's guide for MVC
You're correct - you'll need to use something like Unity, Ninject or Autofac to get this running.
Essentially - the steps are roughly the same regardless of the tech used.
Using unity as an example:
1) In your MVC project, use NuGet to add "Unity Bootstrapper for MVC". (right click references, manage nuget packages, search for unity online, select "Unity Bootstrapper for MVC"
This will add a few things to your project - the most interesting is the unityConfig.cs in App_start.
2) In unityConfig.cs - find RegisterTypes method
RegisterTypes is where you tell the unity container "when you need one of X, use implementation Y" - in your case "when you need an IEmployeeService, use EmployeeService"
3) In register types - add your type mappings - for example, in your case:
container.RegisterType<IEmployeeService, EmployeeService>();
AND
4) Bit more complicated: as you have IRepository and you need this to resolve your employeeService correctly you'll also have to register a generic type against a generic implementation (it's a little odd). Looking at your types, it's going to be something like:
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
(You'll need to resolve the namespaces according to your projects).
So - what this is saying is...
Right MVC - when you need an IEmployeeService use employeeService, and
when you need an IRepository<>, use Repository<>
Now - because of the webActivator that was added during the NuGet installation (right next door to UnityConfig.cs), that should be it - the webActivator sets the DependencyResolver.Current to something that uses this unityContainer.
Beacause of this, MVC will now use this new unityContainer whenever it tries to instantiate your controllers, resolving the type mappings on the way.
The webActivator and unityConfig classes do alot of the heavy-lifting for you, just elaborate registerTypes and you should at least have a foot-hold in the solution.
HTH - good luck.
PS - DI itself is a massive subject - far too much for here, you'll bump into all sort of weird and wonderful things (supplying Ctor args for resolutions, lifetime management just for a start!) - it's fun, but not trivial, so you'll have to excuse me if this doesn't work "out of the box" (it's almost impractical to think it would) - this is merely just a vague attempt to give you a foothold in the subject!
For more info on unity - I suggest you read up here (Dev guide to using Unity on MSDN)
I'm trying to implement a role provider using a separate EF repository class, as an injectable dependency, to access my roles store. My problem is that the role provider is defined in configuration (web.config) and therefore is not instantiated via the Unity DI container. I haven't been able to find a way to either shift the configuration to code or get hold of the role provider after it's built to call container.BuildUP() on it. Any suggestions would be appreciated.
I think that my question's solution is fairly well covered here:
Property injection in custom membership provider using Castle
If I'd searched on MembershipProvider instead of RoleProvider probably would have found it the first time through.
Just to summarize my solution, the link lead me to the Common Service Locator library at codeplex.
It and the Unity adapter for it are included in the Nuget package for Unity 3. So I already had it.
I added one line to the end of the Compose() method of my CompositionRoot class:
var locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
And I can now access the locator/container thru the static ServiceLocator class in the constructor of my RoleProvider:
public IAuthorizationManager Manager {get; set;}
public MyRoleProvider()
{
var locator = ServiceLocator.Current;
Manager = locator.GetInstance<IAuthorizationManager>();
}
(Of course, you need 'using' statements for Microsoft.Practices.ServiceLocation)
I can't seem to figure out how to get dependency injection to work in a custom membership provider. I'm aware that the membership provider base class is managed deep in ASP.NET, but there should be some way to get dependency injection to work on private data members.
I'm using Unity and see this issue only in my membership and role providers
my issue is two fold:
The application complains that it doesn't have a parameterless
constructor for "MyMembershipProvider"
even if I try this: https://stackoverflow.com/a/9815425/595335, security service is null in the ValidateUser method
public class MyMembershipProvider : MembershipProvider
{
public ISecurityService securityService;
public MyMembershipProvider(ISecurityService securityService)
{
this.securityService = new SecurityService();
}
public override bool ValidateUser(string username, string password)
{
User user = securityService.GetUserByUsername(username);
...ommited...
}
It may not be as ideal, but you might need to use property injection instead of constructor injection.
The problem is that your provider is created by a static class. Since static classes are not "instantiated" and live for the lifetime of the app, there is no way to allow your DI framework to instantiate a static class.
There are potential workarounds, but you can't use constructor injection. These workarounds are also brittle and overly complex. In short, it's a PITA and is just not worth the effort. You would probably save yourself a lot of headache by either forgettinga bout DI in a membership provider, or forgetting about using Membership and roll a custom IIdentity and IPrincipal solution.
I'm new to Ninject and I'm having problems using it with a custom membership provider.
My membership provider has a repository interface passed in. It looks like:
public class CustomMembershipProvider : MembershipProvider
{
public CustomMembershipProvider( IRepository repository )
{
}
}
I'm using the code thats part of the Account Model in the MVC app as a starting point.
However when it calls Membership.Provider I get an error saying No parameterless constructor defined for this object.
I've setup the bindings in ninject to bind a IRepository to a Repository class which work as I've testing this in a controller.
What are the correct bindings in Ninject to use for Membership.Provider?
This is how it should be done today with new versions of both MVC and Ninject (version 3):
You have access to the DependencyResolver instance and Ninject sets itself as the current DependencyResolver. That way you don't need hacks to get access to the static Ninject kernel. Please note, my example uses my own IUserService repository for Membership...
IUserService _userService = DependencyResolver.Current.GetService<IUserService>();
The best solution I found was the following:
private IRepository _repository;
[Inject]
public IRepository Repository
{
get { return _repository; }
set { _repository= value; }
}
public CustomMembershipProvider()
{
NinjectHelper.Kernel.Inject(this);
}
Where NinjectHelper is a static helper class to get the Kernal from.
Since the membership collection and the Membership.Provider instance are created before Ninject can instantiate them, you need to perform post creation activation on the object. If you mark your dependencies with [Inject] for your properties in your provider class, you can call kernel.Inject(Membership.Provider) - this will assign all dependencies to your properties.
I haven't used Ninject ever.
but in StructureMap i set this dependency:
expression.For<MembershipProvider>().Add(System.Web.Security.Membership.Provider);
and it works fine.
I'm trying to implement my custom authorize attribute like:
public class MyCustomAuth : AuthorizeAttribute
{
private readonly IUserService _userService;
public MyCustomAuth(IUserService userService)
{
_userService= userService;
}
... continued
}
I am using Castle Windsor for automatically resolve the dependency.
When I try to use it as an attribute of an action method obviously I am asked to pass the parameter or I need to have a parameter-less constructor that should resolve in some way it's dependency.
I tried to inject the dependency with a property but Windsor is not injecting it.
The only option I see now would be to instantiate manually the concrete object dependency loosing the benefit of Windsor.
How would you solve this problem?
You cannot use DI with attributes - they're metadata;
public class MyCustomAuth : AuthorizeAttribute
{
public void OnAuthorization(...)
{
IUserService userService = ServiceLocator.Current.GetInstance<IUserService>();
}
}
Learn about Windsor/ServiceLocator here.
See similar question here.
You can use a custom ControllerActionInvoker and inject property dependencies (you can't do constructor injection because the framework handles instantiation of attributes). You can see a blog post I just did on this technique.
You did not supply any castle code or configuration examples. Therefore, I am assuming you are new to castle and unfimilar with the registration process.
First of all, any object you want to act upon must come from Castle Windsor via a registered type. With that said, you are going down the wrong path by trying to use castle windsor with attributes - because attributes are not referenced in code, but instead are reflected upon. Therefore, there is not a place for IoC (Castle Windsor in this case) to create the object.
I say this, because what you are trying to accomplish has already been done via different means. First of all, put your dependency injection on your controllers.
public class PostController
{
private IUserService _userService;
public PostController (IUserService userService)
{
_userService = userService;
}
// other logic
}
For Castle to work, you have register all types. So, you have to register IUserService, and what services implement that interface, within Castle Windsor. You can do this via a manual process in your global.asax with container.AddComponentWithLifeStyle; or the more preferred method is to use a configuration file.
Using a configuration file, your IUserService would look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<components>
<!--lifestyle="singleton|thread|transient|pooled|webrequest|custom"-->
<component
id="UserService"
service="MyMvcProject.IUserService, MyMvcProject"
type="MyMvcProject.UserService, MyMvcProject"
lifestyle="transient">
</component>
</components>
</castle>
MyMvcProject is the name of your project and make sure to use the exact namespace and fully qualified name of the interface, and type. Please give code samples of your actual namespaces, else we cannot help you any further.
Before that will work, you will need to modify your app.config or web.config to register the searchGroup for Castle Windsor:
<configSections>
<section name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
</configSections>
<castle configSource="castle.config"/>
Now that you are all registered and setup, it is time to tell your MVC application to "Use Castle Windsor to create each instance of my Controllers." Doing this means that Castle Windsor, being an Inversion-of-Control (aka IoC) container, will inspect the dependencies of your controller and see that it depends on IUserService and implement an instance of UserService. Castle will look into its configuration of registered types and see that you have registered a service for IUserService. And, it will see in your configuration file that you want to implement the concrete class of UserService that implements IUserService. So, the IoC container will return UserService when a dependency on IUserService is requested.
But before that can happen, you have to tell your MVC application to use your configuired IoC container. You do this by registering a new ControllerFactory. To do that, see my answer over at this question:
Why is Castle Windsor trying to resolve my 'Content' and 'Scripts' folder as a controller?
And notice the global.asax part of how to register that code. It works quite well!
Now, when all of that is said and done, you want to authorize a user. Use the normal [Authorize] that implements Forms Authentication, and use your _userService to grab any user details of the signed in user.