Should my User model inherit MembershipUser - c#

I'm looking at creating a custom membership provider in ASP.Net MVC3 and am struggling to see how it all fits together...
I'm really looking for some best practice approaches on how to do this.
I have a User model (represnting a Users table in my database). In order to use this with the MembershipProvider functionality, should this model inherit MembershipUser? There are a number of fields in MembershipUser that I do not care about - do these have to be in the underlying SQL table for this approach to work (obviously this seems redundant, as I'll never use the columns?)
For example - should I make my model inherit MembershipUser like this?
/// <summary>
/// Class representing a registered user based on the Users database table.
/// </summary>
public class User : MembershipUser
{
public int Id { get; set; }
//here I can access some other properties I will use which are already in MembershipUser...
//Addtional properties I need specific to my app.
public bool NotifyOfNewBlog { get; set; }
public bool NotifyOfNewWallPosts { get; set; }
//...plus many more.
}
When it comes to using Membership.GetUser() further down the line, do I then cast that object everytime back to my original User object to be able to access the additional properties?
Is this the approach I should be taking? Or do I a separate User model and then a CustomMembershipUser model which links back to the DB model?
Will EF be able to save/update/insert a User model if it doesn't have all the MembershipUser columns as objects in the table? Is this even anywhere near the correct approach? As you can see, I'm scratching my head a bit here.
Any advice/thoughts/ideas are much appreciated.

As far as inheriting the MembershipUser object goes, you could do that, and in your implementation of MembershipProvider, just cast up to your derived type, but I personally would not do this, simply because you are then at the mercy of future changes to this type breaking your derived type (although this could be said about most of the framework I guess). I would instead put these additional values into a profile, and roll your own ProfileProvider, (don't use the Sql one it is rubbish from my experience).
"There are a number of fields in MembershipUser that I do not care about - do these have to be in the underlying SQL table for this approach to work (obviously this seems redundant, as I'll never use the columns?)"
If you are rolling your own, you can just not save this in the Db. After all, you are implementing the MembershipProvider methods (GetUser etc etc) so what you do with the MembershipUser object passed to you, is up to you. You can just ignore these, and not validate or store them.

I had quite the same problem a while ago, and in the end i decided not to pollute my EF models with Membership logic. I have my data access tier in my application, and my EFMembershipProvider use that when he has to save/update data. If i have to GET user data in my application (other than in the membership itself), i don't use Membership (and i don't have to cast nothing).
I want to make clear that if you implement your own Membership Provider
public class EFMembershipProvider : MembershipProvider
you can abstract the underlying functionality of the membership facility to use your own models/repositories.
You can find an example of an implemented membership provider for EF in the MVC3 boilerplate
https://github.com/crdeutsch/MVC3-Boilerplate
Under Web/Infrastructure (though you probably want to modify large parts of it).

Related

Which class should be responsible for creating ID for entity?

I'm struggling a little bit with following problem. Let's say I want to manage dependencies in my project, so my domain won't depend on any external stuff - in this problem on repository. In this example let's say my domain is in project.Domain.
To do so I declared interface for my repository in project.Domain, which I implement in project.Infrastructure. Reading DDD Red Book by Vernon I noticed, that he suggests that method for creating new ID for aggregate should be placed in repository like:
public class EntityRepository
{
public EntityId NextIdentity()
{
// create new instance of EntityId
}
}
Inside this EntityId object would be GUID but I want to explicitly model my ID, so that's why I'm not using plain GUIDs. I also know I could skip this problem completely and generate GUID on the database side, but for sake of this argument let's assume that I really want to generate it inside my application.
Right now I'm just thinking - are there any specific reasons for this method to be placed inside repository like Vernon suggests or I could implement identity creation for example inside entity itself like
public class Entity
{
public static EntityId NextIdentity()
{
// create new instance of EntityId
}
}
You could place it in the repository as Vernon says, but another idea would be to place a factory inside the constructor of your base entity that creates the identifier. In this way you have identifiers before you even interact with repositories and you could define implementation per your ID generation strategy. Repository could include a connection to something, like a web service or a database which can be costly and unavailable.
There are good strategies (especially with GUID) that allow good handling of identifiers. This also makes your application fully independent of the outside world.
This also enables you to have different identifier types throughout your application if the need arises.
For eg.
public abstract class Entity<TKey>
{
public TKey Id { get; }
protected Entity() { }
protected Entity(IIdentityFactory<TKey> identityFactory)
{
if (identityFactory == null)
throw new ArgumentNullException(nameof(identityFactory));
Id = identityFactory.CreateIdentity();
}
}
Yes, you could bypass the call to the repository and just generate the identity on the Entity. The problem, however, is that you've broken the core idea behind the repository: keeping everything related to entity storage isolated from the entity itself.
I would say keep the NextIdentity method in the respository, and still use it, even if you are only generating the GUID's client-side. The benefit is that in some future where you want to change how the identity's are being seeded, you can support that through the repository. Whereas, if you go with the approach directly on the Entity, then you would have to refactor later to support such a change.
Also, consider scenarios where you would use different repositories in such cases like testing. ie. you might want to generate two identities with the same ID and perform clash testing or "does this fail properly". Having a repository handle the generation gives you opportunity to get creative in such ways, without making completely unique test cases that don't mimic what actual production calls would occur.
TLDR; Keep it in the repository, even if your identifier can be client-side generated.

Entity Framework classes vs. POCO

I have a general difference of opinion on an architectural design and even though stackoverflow should not be used to ask for opinions I would like to ask for pros and cons of both approaches that I will describe below:
Details:
- C# application
- SQL Server database
- Using Entity Framework
- And we need to decide what objects we are going to use to store our information and use all throughout the application
Scenario 1:
We will use the Entity Framework entities to pass all around through our application, for example the object should be used to store all information, we pass it around to the BL and eventually our WepApi will take this entity and return the value. No DTOs nor POCOs.
If the database schema changes, we update the entity and modify in all classes where it is used.
Scenario 2:
We create an intermediate class - call it a DTO or call it a POCO - to hold all information that is required by the application. There is an intermediate step of taking the information stored in the entity and populated into the POCO but we keep all EF code within the data access and not across all layers.
What are the pros and cons of each one?
I would use intermediate classes, i.e. POCO instead of EF entities.
The only advantage I see to directly use EF entities is that it's less code to write...
Advantages to use POCO instead:
You only expose the data your application actually needs
Basically, say you have some GetUsers business method. If you just want the list of users to populate a grid (i.e. you need their ID, name, first name for example), you could just write something like that:
public IEnumerable<SimpleUser> GetUsers()
{
return this.DbContext
.Users
.Select(z => new SimpleUser
{
ID = z.ID,
Name = z.Name,
FirstName = z.FirstName
})
.ToList();
}
It is crystal clear what your method actually returns.
Now imagine instead, it returned a full User entity with all the navigation properties and internal stuff you do not want to expose (such as the Password field)...
It really simplify the job of the person that consumes your services
It's even more obvious for Create like business methods. You certainly don't want to use a User entity as parameter, it would be awfully complicated for the consumers of your service to know what properties are actually required...
Imagine the following entity:
public class User
{
public long ID { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string Password { get; set; }
public bool IsDeleted { get; set; }
public bool IsActive { get; set; }
public virtual ICollection<Profile> Profiles { get; set; }
public virtual ICollection<UserEvent> Events { get; set; }
}
Which properties are required for you to consume the void Create(User entity); method?
ID: dunno, maybe it's generated maybe it's not
Name/FirstName: well those should be set
Password: is that a plain-text password, an hashed version? what is it?
IsDeleted/IsActive: should I activate the user myself? Is is done by the business method?
Profiles: hum... how do I affect a profile to a user?
Events: the hell is that??
It forces you to not use lazy loading
Yes, I hate this feature for multiple reasons. Some of them are:
extremely hard to use efficiently. I've seen too much times code that produces thousands of SQL request because the developers didn't know how to properly use lazy loading
extremely hard to manage exceptions. By allowing SQL requests to be executed at any time (i.e. when you lazy load), you delegate the role of managing database exceptions to the upper layer, i.e. the business layer or even the application. A bad habit.
Using POCO forces you to eager-load your entities, much better IMO.
About AutoMapper
AutoMapper is a tool that allows you to automagically convert Entities to POCOs and vice et versa. I do not like it either. See https://stackoverflow.com/a/32459232/870604
I have a counter-question: Why not both?
Consider any arbitrary MVC application. In the model and controller layer you'll generally want to use the EF objects. If you defined them using Code First, you've essentially defined how they are used in your application first and then designed your persistence layer to accurately save the changes you need in your application.
Now consider serving these objects to the View layer. The views may or may not reflect your objects, or an aggregation of your working objects. This often leads to POCOS/DTO's that captures whatever is needed in the view. Another scenario is when you want to publish objects in a web service. Many frameworks provide easy serialization on poco classes in which case you typically either need to 1) annotate your EF classes or 2) make DTO's.
Also be aware that any lazy loading you may have on your EF classes is lost when you use POCOS or if you close your context.

Accessing HttpContext and User Identity from data layer

I need to implement AddedBy/ChangedBy type fields on my Base Entity that all other entities inherit from ( Fluent Nhibernate ).
Accessing HttpContext.User.Identity from within my Repository/Data layer is probably not a good idea.. or is it ?
What's the best way to grab my user ( current identity ) information to record who the records were added or changed by ?
Re-factoring the entire application to include user information in repository calls would be silly. I'm sure there is a better, more generic way.
Access the HttpContext from the Data Layer makes the life harder, specially if you use Unit Tests. The solution is to create a service to provide application wide user information, something like:
public interface ICurrentUserService {
string UserName {get;}
string UserId {get;}
string HostIP {get;}
// etc.
}
Then you can implement the concrete service and inject it using your
preferred IoC container.
public class CurrentWebUserService : ICurrentUserService {
// implement interface members
public CurrentWebUserService(HttpContext context) { ... }
public string UserName { get { ... } }
// etc.
}
// maybe you want a stub service to inject while unit testing.
public class CurrentUserServiceStub : ICurrentUserService {
}
// data layer
public class MyDaoService {
public DaoService(ICurrentUserService currentUser) { ... }
}
You're correct. Referencing your HttpContext.User.Identity class from within your repository is not a good idea. The HttpContext is a UI concern and as such, should go no further than the UI layer.
What you should be doing is harnessing an IoC container (such as StructureMap) to inject your dependency (HttpContext.User.Identity) details into your repository, or any other layer such as the service layer via dependency injection.
For an example of how this can be setup (in this instance it's the session object) see the latter part of this answer.
HttpContext.Current is a static member that you can access anywhere in the application.
https://msdn.microsoft.com/en-us/library/system.web.httpcontext.current%28v=vs.110%29.aspx
Obviously there are problems, such as if you don't HAVE an HttpContext when the code is called.
So HttpContext.Current.User should work for you. I wouldn't recommend it, because your underlying data access code is now depending on stuff that should be kept to your display or controller logic, etc. Also, this assumes that your data access is in the web application itself and not part of, say, an external library.
Personally, I'd just pass in the salient details, like user ID and access time, as part of the add and modify database calls. Make an "AuditTrail" class or something. That would let you reuse that data access code (always a good thing) in another project without having to pull out all the HttpContext stuff.
The AddedBy/ChangedBy field is potentially important in any data backend. You may even want to have AccessedBy for logging purposes. Therefore, you would want to think that the user information is a central part of your data. It is also possible that you may want other details such as the client's IP address logged for security reasons. Probably a good idea to have the entire context rippled down to the data layer so that you have the flexibility to capture and save the client information.
I have used a factory to get the correct repo with or without a "CurrentUser" since sometimes you need to know who the user is and sometimes you don't.
//I have a current user that I got from the Identity
var repo = RepoFactory.GetRepo<Users>(currentUserId);
//I don't have a current user
var repo = RepoFactory.GetRepo<Users>()
This way you can pull the Identity from the HttpContext and pass only details you need to the repo.
HttpContext.User.Identity is of System.Security.Principal.IIdentity type. Don't mess it up with Microsoft.AspNet.Identity library (NuGet package) which is actually pointed by asp.net-identity tag in your question.
Identity lib consists of common part and its ORM implementation. Typically it is for Entity Framework. But if you're going to use Microsoft.AspNet.Identity package in the way you describe with NHibernate, then you most likely will need this package.
I didn't use it, but I used EF implementation. See this answer how to inherit of predefined IdentityDbContext<T> where T is your User class. I guess, NH has similar fluent configuration. Then you can link any of entities in your DbContext to AppUser

Can I dynamically/on the fly create a class from an interface, and will nHibernate support this practice?

I’ve done some Googling but I have yet to find a solution, or even a definitive answer to my problem.
The problem is simple. I want to dynamically create a table per instance of a dynamically named/created object. Each table would then contain records that are specific to the object. I am aware that this is essentially an anti-pattern but these tables could theoretically become quite large so having all of the data in one table could lead to performance issues.
A more concrete example:
I have a base class/interface ACCOUNT which contains a collection of transactions. For each company that uses my software I create a new concrete version of the class, BOBS_SUB_SHOP_ACCOUNT or SAMS_GARAGE_ACCOUNT, etc. So the identifying value for the class is the class name, not a field within the class.
I am using C# and Fluent nHibernate.
So my questions are:
Does this make sense or do I need to clarify more? (or am I trying
to do something I REALLY shouldn’t?)
Does this pattern have a name?
Does nHibernate support this?
Do you know of any documentation on
the pattern I could read?
Edit: I thought about this a bit more and I realized that I don't REALLY need dynamic objects. All I need is a way to tie objects with some identifier to a table through NHibernate. For example:
//begin - just a brain dump
public class Account
{
public virtual string AccountName { get; set; }
public virtual IList Stuff { get; set; }
}
... somewhere else in code ...
//gets mapped to a table BobsGarageAccount (or something similar)
var BobsGarage = new Account{AccountName="BobsGarage"};
//gets mapped to a table StevesSubShop(or something similar)
var StevesSubShop = new Account{AccountName="StevesSubShop"};
//end
That should suffice for what i need, assuming NHibernate would allow it. I am trying to avoid a situation where one giant table would have the heck beat out of it if high volume occurred on the account tables. If all accounts were in one table... it could be ugly.
Thank you in advance.
Rather than creating a class on the fly, I would recommend a dynamic object. If you implement the right interfaces (one example is here, and in any case you can get there by inheriting from DynamicObject), you can write
dynamic bobsSubShopAccount = new DynamicAccount("BOBS_SUB_SHOP_ACCOUNT");
Console.WriteLine("Balance = {0}", bobsSubShopAccount.Balance);
in your client code. If you use the DLR to implement DynamicAccount, all these calls get intercepted at runtime and passed to your class at runtime. So, you could have the method
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (DatabaseConnection.TryGetField(binder.Name, out result))
return true;
// Log the database failure here
result = null;
return false; // The attempt to get the member fails at runtime
}
to read the data from the database using the name of the member requested by client code.
I haven't used NHibernate, so I can't comment with any authority on how NHibernate will play with dynamic objects.
Those classes seem awfully smelly to me, and attempt to solve what amounts to be an actual storage layer issue, not a domain issue. Sharding is the term that you are looking for, essentially.
If you are truly worried about performance of the db, and your loads will be so large, perhaps you might look at partitioning the table instead? Your domain objects could easily handle creating the partition key, and you don't have to do crazy voodoo with NHibernate. This will also more easily permit you to not do nutty domain level things in case you change your persistence mechanisms later. You can create collection filters in your maps, or map readonly objects to a view. The latter option would be a bit smelly in the domain though.
If you absolutely insist on doing some voodoo you might want to look at NHibernate.Shards, it was intended for easy database sharding. I can't say what the current dev state and compatibility is, but it's an option.

Overriding SQLMembershipProvider

Is there built in methods into .net framework to do the following:
Get role GUID from user name/user GUID
Get role name from role GUID
So far I have been sending queries to the asp_roles and asp_users tables to obtain that information and I'm wondering if there is a nicer way of doing this?
I have the following methods that I store in the ASPUtilities class:
getRoleGUID(guid userGuid) { LINQ joins }
getRoleGuid(string userName) { LINQ joins }
getRoleName(guid roleGuid) { LINQ joins }
EDIT:
I have just looked into extending SQLMembershipProvider examples.
Few examples completely override the SQLMembershipProvider, but I think what I'm interested is just adding few extra methods to deal with the roles by using LINQ. Is this feasible?
If you extend the SQLMembership provider, it will do the exact same thing, send queries to the database to get that information since the roleID is not stored in session. If you don't want to go through that much trouble, you could do a few things.
Create a custom class with these methods that you can call and will return the ID for you of your role. Essentially, move all of your queries to one location.
Store the role ID in session on login. Call your method you created above once and don't requery everytime. Not 100% of the security risks with this one, however, since you are storing some possibly sensitive role information, the id, in session. Might just be overly cautious though :)

Categories