I would like to know if someone can assist me with this little dilemma...
I am following a clean architecture project setup using .net core 3.1. With projects:
API
Domain
Infrastructure
Application
In Domain I do not reference any projects (or package) everything else references from it.
And I have the table below in Domain:
Company Table
I have added my identity to the Infrastructure later in which I have have a ApplicationUser which extends IdentityUser.
So the scenario is as follows:
user signs up and later gets attached to a company. A company can have many users (this being AspNetUser)
So when a user signs in he is attached to that company and can do certain actions under that company
And when I retrieve the company it will have a list of users thats attached to it.
So the question I have is, what do I do so that I can have a Company with a collection of users, also without having to add a reference From Domain to infrastructure
Common pattern to resolve this issue is to define an abstraction of your user class or an interface in the domain layer. This abstraction is used in the company class and the user implementation in infrastructure project derives from it.
If inheritance is not an option you can go for an interface in domain project and have an adapter in infrastructure project wrapping the actual user implementation providing access to its properties.
Related
I'm starting with the base architecture of a monolithic project, I'm trying to implement a generic DbContext within a layered architecture, specifically within the Common project, which will be the reference in all the other layers.
My problem is given by the use of AspNet Identity, where the DbContext must Inherit from IdentityDbContext and pass an argument of type ApplicationUser or TUser.
The issue is that my ApplicationUser class is inside the Domain project, which contains all the classes that represent my database model.
I don't want my Common project to have the reference of some other project, because it assumes that this would be a generic project for general use.
How is the best way to solve this architecture?
enter image description here
I try to have a BaseUserEntity base class inside the Common project and have this be my TUser that needs IdentityDbContext, but it gets complicated when I have to generate the configuration of the database tables...
I have a model where I will implement several types of users.
UserA
UserB
And that all these inherit from my ApplicationUser, due to the inconvenience that I have, it could not move forward with the development.
I'm using the domain architecture and facing following issue when using Identity from .NET framework.
To use usermanager etc. in my controllers, I did place the Identity classes in the front-ent/API layer. All my entity classes are in the domain layer (data access layer takes care of db access).
So far, so good.
But now, I do have a class Company which has a one to many relationship to the AppUser: IdentityUser class. That works, if I place the Company class in the API layer. However, I need also to use the Company class in the domain layer. That doesn't work as I cannot reference the API layer from Domain layer (circular reference).
Is there a way to overcome this?
Thanks in advance!
N.
I'm trying to implement Identity 2.0 in my ASP.NET MVC 5 solution that abides the onion architecture.
I have an ApplicationUser in my core.
namespace Core.DomainModel
{
public class ApplicationUser {...}
}
In my Data Access Layer I'm using Entity Framework 6.1 and my context derives from IdentityDbContext and herein lies the problem. ApplicationUser needs to derive from Microsoft.AspNet.Identity.EntityFramework.IdentityUser
namespace Infrastructure.DAL
{
public class TestContext : IdentityDbContext<ApplicationUser> {...}
}
My domain model shouldn't reference Microsoft.AspNet.Identity.EntityFramework that would go against the idea of the onion.
What's a good solution?
Yep, this is the big problem with the Identity framework which I have found no good solution yet.
I contemplated adding EF to my domain project, but decided against it in one project: domain models are not aware about ApplicationUser, only using Id for the current user which they get from
ClaimsPrincipal.Current.Claims
.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)
.Value
In that project I kept all Identity code in Web and Data projects.
In my other project I have added Identity and EF all over the place, including Domain project. And guess what? nothing bad happened.
I also have looked on solutions like already provided link to Imran Baloch' blog. It looked like a lot of work to me to gain no customer value.
Just to repeat myself, there is no good solution to separate EF from Identity without rewriting a pile of code (don't like it). So either add EF to your Domain project (don't like it) or keep your Identity code in Web/Data project (sometimes not possible, so I also don't like it).
Sorry to say, but this is a low-level limitation of .Net.
You can inherit IUser from the Core namespace and the usermanager will be happy. You will need to replace the IUserStore with your own implementation. Then initializer the user manager something like:
new UserManager<ApplicationUser>(new YourNameSpace.UserStore<YourApplicationUser>()))
The problem is that you are trying to use the Onion pattern. In its foundations that you will always build dependencies.
Thrive for single responsibility of your models you are creating. You can do easily this by trying to follow Domain Driven Design properly by implementing individual models per layer:
BusinessLogic.Models.ApplicationUser
Presentiation.Models.ApplicationUser
DAL.Models.ApplicationUser
Note that all of those models are different classes even if they have 100% same properties (although it is never 100%). The drawback is that you may need to map from one model to another, but if you are trully aim for clean, modular and extensible architecture - that is the way.
Hint you can use Automapper (or ExpressMapper) to avoid code needed for mapping.
I was trying to learn Asp.Net Identity and
in this tutorial,
Create an Entity Framework Code First ToDo model in Models\AppModels,cs part MyUser class
inherits from IdentityUser class and MyDbContext inherits from IdentityDbContext<MyUser> class. Why is that?
Lets say I have a User class that holds all the information of the user of my web application, should that class inherit from IdentityUser, and should my DbContext inherit from IdentityDbContext<User>?
Also, what are the advantages of inheritng dbcontext class from IdentityDbContext<TClass> over plain DbContext class as done in MVC 4
ASP.Net MVC 5.0 uses OWIN implemenation for plug and play.
There are couple of interfaces designed for this
FROM Scott Allen Article
IUser
A user object must implement the IUser interface, which requires every
user to have at least an ID and a name. The most notable aspect of
IUser is the Id property of type string. Strings work well for GUIDs
but can be a bit tricky when using integers for keys as is common with
SQL Server. More details in a future post.
IUserStore
The I*Store interfaces in the Core Identity assembly are factored to offer various levels of functionality.
IUserStore defines the bare minimum functionality you’d want for users
– create, retrieve, update, and delete (CRUD) functionality. If your
website wants to allow users to create local accounts with passwords,
you’ll want a component implementing IUserPasswordStore (which is an
IUserStore). For third party logins (Twitter and Facebook, for
example), add in IUserLoginStore, and for claim storage there is an
IUserClaimStore. Also, not shown in the class diagram above, is a
collection of interfaces for roles (IRole, IUserRoleStore, etc). Let
the debate on roles versus claims begin.
UserManager
The UserManager is a concrete class and it is the UserManager that provides the domain logic for working with user information. The UserManager knows when to hash a password, when to validate a user, and how to manage claims.
There are a few extensibility points with the UserManager, for example, the manager has a number of properties you can use to set a custom user validator (any object implementing IIdentityValidator), a custom password validator, and a custom password hasher. The primary extensibility point is via the UserManager constructor, which allows you to pass in any object implementing IUserStore. If you want to use a UserManager to manage user information stored in SQL Server, we’ll look at pre-built classes to do this in a later post, but it is also easy to create an IUserStore to work with a document database or other forms of storage.
Remember an IUserStore doesn’t know how how to work with user passwords, only an IUserPasswordStore knows about passwords. The UserManager is aware of the different core interfaces and will try to work with the capabilities of the store object given in the constructor. For example, if you use FindByIdAsync the UserManager can use the user store to query for a user by ID, but if you invoke FindAsync (which takes a username and a password), and the underlying store doesn’t implement the IUserPassword store interface, the UserManager will be forced to throw an exception.
It’s tricky to use a single concrete class for everything from users to passwords to claims, and tradeoffs must be made. We’ll also look at some of the tradeoffs in upcoming posts.
EDIT: Check out Implementing ASP.Net Identity
Now ASP.Net identity supports generic IdentityUser<TKey> before it was a string,i.e UserId was a string
The IdentityDbContext<> class is a class that inherits from DbContext as you would usually do but provides ready DbSets for Roles and Users.
See class doc here:
http://msdn.microsoft.com/en-us/library/microsoft.aspnet.identity.entityframework.identitydbcontext%28v=vs.111%29.aspx
Yes, your user dto should inherit from IdentityUser and any additional fields you want in your database associated with your user can be added to that class.
This makes it much easier to add additional fields to your database that are associated with your user and if you are using Entity Framework migrations and database initializes it means that you can now generate the entire Identity database from your DbContext.
I'm new to ASP.NET MVC and I've been developing a MVC 5 application with individual user authentication. I've been doing a layered pattern when doing my applications like separating Model layer, DAL layer, Repos, etc. etc. but now in MVC 5, I want to be able to use the user and role management and authentication which they call Identity, and then still have that layered structure to my application because right now it seems Identity is pretty much coupled with the MVC project itself with the user and role models in there and the context too.
What I did in my application for now is I have all my supposed-to-be-separate layers like my DAL, UnitOfWork, Repos, other models, etc in the MVC project (in separate folders!) just to make it work, for now. And I know it's just not the right way to do it.
So can anyone point me to some good examples or articles about this or explain it directly if it's possible or not and how? Google hasn't been friendly to me about this one. Thanks!
Here is a quick draft of what I'd try...I would create these layers:
Contoso.Core (Class Library)
Contoso.Data (Class Library)
Contoso.Service (Class Library)
Contoso.Web.Framework (Class Library)
Contoso.Web (ASP.NET MVC 5.0)
Contoso.Core:
This layer holds all my entities/classes representing my database TABLES.
So for example, I would have a:
User.cs class.
Product.cs class
ProductDetail.cs class
Etc..
Some people call these entities/classes: the Domain Objects, others call it the POCO classes.
Either or, these entities/classes are defined in the Core Layer since they may (or may not) be used amongst the other layers.
Contoso.Data:
This layer is where I define my ContosoDbContext.cs class. It is inside that file that I have all my DbSet<> defined.
So for example, I would have the following inside my ContosoDbContext.cs:
public DbSet User { get; set; }
public DbSet Product { get; set; }
public DbSet ProductDetail { get; set; }
Needless to say, the Contoso.Data layer WILL HAVE A DEPENDECY on the Contoso.Core layer.
In addition, it is inside that Contoso.Data layer that I would have my Generic Repository and anything related to "data access".
Contoso.Service:
This layer would be where I place all my business rules. For example, I may have a UserService.cs class that could have a Login() method. The Login() method would receive a username/password and call the Repository to lookup the user.
Because the Service layer needs the Repository, I WILL HAVE A DEPENDENCY on the Contoso.Data layer AND because I'll be playing around with the User class (which happens to live inside the Contoso.Core layer), I WILL ALSO HAVE A DEPENDENCY on the Contoso.Core layer.
Contoso.Web.Framework:
This layer would have a dependency on the Contoso.Core, Contoso.Data and Contoso.Service.
I would use this Contoso.Web.Framework layer to configure my Dependency Injection.
Contoso.Web:
The final layer, the MVC 5.0 application, would have a dependency on the Contoso.Web.Framework AND on the Contoso.Service AND on the Contoso.Core layers.
The Controllers, would invoke methods living inside the classes defined in your Contoso.Service layer (for example the Login() method).
The Login() method may or may not, for example, return a User class (null or populated) and because it returns a User class AND BECAUSE we are inside a Controller, our Contoso.Web layer needs a dependency on the Contoso.Service and Contoso.Core.
Of course, I haven't detailed everything here or every layer but this is just to give you an example of the type of architecture I’d use.
So far, I haven't answered your question but with little I know about MVC 5.0 and its new Identity mechanism, I believe the Contoso.Core layer would need to have a dependency on Microsoft.AspNet.Identity.EntityFramework in addition to the Microsoft.AspNet.Identity.Core
Likewise, my ContosoDbContext.cs class would need to implement the IdentityDbContext interface which happens to belong to the Microsoft.AspNet.Identity.EntityFramework.dll.
This means my Contoso.Data layer would have a dependency on Microsoft.AspNet.Identity.EntityFramework and most probably the Microsoft.AspNet.Identity.Core as well...
As you say, when you create a new MVC 5.0 project, all of this exist and is defined within the single application. Nothing is or has been decoupled into layers. So in the above architecture the ContosoDbcontext.cs class lives inside the Contoso.Data layer and NOT directly inside the ASP.NET MVC application.
Since I haven't tried the new ASP.NET Identity nor have I tried to decouple things around, I wouldn't know how to honestly answer your question. I guess you'll have to try and move things around.
If and when you do, feel free to tell us how it went and what are the things/problems you encountered.
Meanwhile, I hope this has helped you shed some light (or not).
Vince