I have an ASP.NET MVC app that I'm working on. I'm using a custom MembershipProvider (MyCustomMembershipProvider) to access membership information because we already have a database with our own schema that I need to use.
I am using classes similar to the NerdDinner 2 example where I have an AccountMembershipService (implementing an IMembershipService) that contains a MembershipProvider so I can inject a different mock provider. However, I have extended the MyCustomMembershipProvider with a few different methods for CreateUser and ChangePassword. These methods are not available in the MembershipProvider unless you know it's a custom one.
Am I going about this incorrectly? Do I need another layer that is an interface that includes my new provider methods?
I'm not fully sure I understand what your problem is. If you're using a wrapper interface over the MembershipProvider, then it shouldn't matter what methods the provider implements because your app is only using the interface, and you can change the interface to whatever you want.
Or are you asking how you would call your custom methods from your Custom provider? If so, then the whole bit about mocking and what not are just red herrings, because it has nothing to do with the problem.
If that is indeed your problem, then you would simply cast the Membership.Provider method to the type of your provider. Something like this:
var myProvider = Membership.Provider as MyCustomerMembershipProvider;
myProvider.CreateUser(...);
Related
I am trying to incorporate Microsoft.Extensions.DependencyInjection into an existing ASP.NET 4.6.1 app.
I know that while .NET Core has it built-in, for 4.6.1 you need to create some initial classes as outlined in http://scottdorman.github.io/2016/03/17/integrating-asp.net-core-dependency-injection-in-mvc-4/. (The article seems to be out of date since the sample code does not show implementation of BeginScope() and Dispose() for IDependencyResolver. If anybody has more updated examples that would be appreciated.)
"Services" accessed by controllers where you are creating instances via constructors is fairly simple but my problem is when I need an instance of "something" that is from a property or method of an existing object.
For example, I have a inherited DbContext that needs an instance of System.Security.Principal.IIdentity that comes from the logged in user.
Another example is an instance of ApplicationUser. ApplicationUser inherits IdentityUser and the current user can be found by calling FindById() method of AppUserManager.
While AppUserManager can easily be instantiated using DI, how can I use DI the inject the output of the FindById() method? I cannot seem to find any documentation or sample code about this for Microsoft based framework. Other frameworks like Unity seem to support Property-based injection.
In essence, can DI be used with all existing classes or do you specifically need to code out the classes to support DI from the beginning? (i.e. only expect parameters to be passed in via constructors and make sure those instances themselves are created via constructors).
The very simple and short answer to your question "Does Microsoft DependencyInjection support non-constructor injection?" is, no.
Out-the-box Microsoft DI does not currently support property injection like other frameworks such as Ninject. If you need that feature, I suggest using those frameworks instead (I cant imagine MS has any plans to add property injection any time soon).
Your other option is to consider how you can refactor your code to use constructor injection instead which is the preferred method
I've really gotten into the DI/IoC things - it makes some things a lot easier. However, I have a few inherited classes that implement a class with a required parameterless constructor, I thus use a service locator to get what I want:
MyMembershipProivder() : MyMembershipProvider(ServiceLocator.Current.GetInstance<...>){}
MyMembershipProivder(IMemberRepo memberRepo){...}
Works perfect. However, since I'm also using MVC3 DependencyResolver I find myself no other way but to do:
var locator = new NinjectServiceLocator(kernel);
DependencyResolver.SetResolver(locator);
ServiceLocator.SetLocatorProvider(() => locator);
DependencyResolver gets used within the MVC app and the ServiceLocator gets used throughout the various class libraries.
Is this the ideal way to do this? Am I missing something?
Update
In the example above, the class is a custom asp.net mebership provider. The asp.net membership provider factory requires for my custom provider to have a parameterless constructor, forcing me to use the service locator to inject the repository that it uses internally.
You don't need the parameterless constructor, the Dependency Resolver will inject your dependency into the constructor:
MyMembershipProivder(IMemberRepo memberRepo){...}
You can replace the default controller factory (to use parameterless constructors in your controllers):
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
You wont need to replace the default controller factory, see Linkgoron's comment below.
Anyway using the Dependency Resolver for your MVC application and the Service Locator for your class libraries is fine, I think.
Hope this helps.
It seems as if you don't really have a choice, unless you can refactor your application to use DI from the start. So, I guess using custom a Service Locator is your best bet.
Although, if the classes you've "inherited" are the controller classes you can just remove the default constructors and be done with it, as MVC will handle everything for you.
I've never seen the ServiceLocator class, is it this?
EDIT:
As I've said, I don't see that you have any other option for decoupling. Service location is probably your best bet, without introducing too much bloat and complexity.
Stuff that's implemented as something built into the .Net FW you should look for specific solutions like the one presented for the Membership Provider.
I want to use asp.net-mvc to write a website, I am quit new to the framework And I am not sure if using MembershipProvider Class is a good idea or not.
Or it is better to implement it by myself.
Could you please tell me what are MembershipProvider drawbacks? and if I use it would I have control over it.
Regardless of the purpose of your website, using MembershipProvider basically gives you flexibility in providing the control of most basic user account management (like login, forget pwd, register, etc).
By inheriting from MembershipProvider class, you are then are exposed to various methods and properties to support membership system. You still have to write code for the implementation of your choice, of course, but eventually you can use multiple or swap them via web.config.
I'm a little confused. In many tutorials, including some in MSDN and ASP.NET website, it's almost always about Membership. But when examining the AccountModel class that's created by default, it's about an objet called _provider of type MembershipProvider.
First, I wonder why they just don't use Membership instead of MembershipProvider?
secondly (and most irritating), why when I try to use _provider.GetAllUsers(), I'm asked to provide also parameters stuff such as pageindex, pagesize, etc. But, when I use Membership.GetAllUsers(), I don't have to supply anything.
What the point of having both Membership and MembershipProvider with slightly different methods?
EDIT
Those are some of the documents I have used to learn how to use Membership. I'm talking about my books.
ASP.NET tutorial,
4GuysFromRolla,
An other 4GuysFromRolla,
MSDN
Thanks for helping
MembershipProvider is an abstract class, meaning you can't create a new instance of it, rather, you must create your own custom class that inherits from it and then implement the functions.
Having a base class as a constructor means you can pass in any class that inherits from it. As others have said, this helps when you're testing. You can pass in a fake implementation or a mock of MembershipProvider to test all the functionality of your controller/class.
If you just use membership instead of a provider, you would have to supply a configuration file with a mock provider for your tests. In this way, you simply create a fake membership provider and use it when you create the MembershipService instance. Membership is just a wrapper around the default MembershipProvider. So as #bzlm said, it is more testable to use the provider rather than the Membership static class.
I have an existing ASP.NET application with lots of users and a large database. Now I want to have it in MVC 2. I do not want to migrate, I do it more or less from scratch. The database I want to keep and not touch too much.
I already have my database tables and I also want to keep my LINQ to SQL-Layer. I didn't use a MembershipProvider in my current implementation (in ASP.NET 1.0 that wasn't strongly supported).
So, either I write my own Membershipprovider to meet the needs of my database and app or I don't use the membershipprovider at all.
I'd like to understand the consequences if I don't use the membership provider. What is linked to that? I understand that in ASP.NET the Login-Controls are linked to the provider. The AccountModel which is automatically generated with MVC2 could easily be changed to support my existing logic.
What happens when a user is identified by a an AuthCookie? Does MVC use the MembershipProvider then?
Am I overlooking something?
I have the same questions regarding RoleProvider.
Input is greatly appreciated.
With MVC it is simple to bypass the Membership and Role provider framework altogether. Sometimes it is easier to do this than to implement custom Membership/Role providers, in particular if your authn/authz model doesn't quite fit the mold of those providers.
First, you should realize that you don't need to write everything from scratch, you can use the core Forms authentication API, which can be used independently of the Membership/Role provider framework:
FormsAuthentication.SetAuthCookie -
Call this after user has been
authenticated, specify the user name
Request.IsAuthenticated - Returns
true if SetAuthCookie was called
HttpContext.Current.User.Identity.Name - Returns the user name specified in the call to SetAuthCookie
So here is what you do in MVC to bypass the Membership/Role provider:
Authentication: In your
controller, authenticate the user
using your custom logic.If
successful, call
FormsAuthentication.SetAuthCookie
with the user name.
Authorization: Create a custom
authorize attribute (deriving from
AuthorizeAttribute) . In the
AuthorizeCore override, implement
your custom authorization logic,
taking the user in
HttpContext.Current.User.Identity.Name
and the roles defined in the Roles
property of the AuthorizeAttribute base class.
Note you can also define properties on your custom
authorization attribute and use that in your authorization logic.
For example you can define a property representing roles as enumerated values
specific to your app, instead of using the Roles property which is just a string.
Affix your controllers and actions with your
custom authorize attribute,
instead of the default Authorize
attribute.
Although you most likely can do this without a custom membership provider, I'm not sure that you save that much effort. Until I read this blog post I thought implementing one was hard, but it's really not. Basically you do this:
Create a class that inherits System.Web.Security.MembershipProvider.
MembershipProvider is an abstract class, so you are readily shown what methods need to be implemented.
The names are pretty self explanatory, so you can probably more or less copy your existing logic.
You might end up doing more than you need with this approach - but on the other hand, anything you might want to use now or in the future that requires a membership provider will already have its needs met.
The source of the SQLMembershipProvider is available here http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx. Take that as a base.
It looks a bit much at first, but you only have to implement the methods you need.
Yes the AuthCookie is used. Yes its a good idea to use the MembershipProvider, because it is well known by other developers.
There are thinks I dont like about it: For example It is not possible to have a transaction that spans the creation of a user by the membershipsystem and some other data in your own datbase. But still it works well.