Asp. Net Core project practices-permission management system (4) Dependency injection, warehousing, service multi-project hierarchical implementation, core permission management system

Source: Internet
Author: User

Asp. Net Core project practices-permission management system (4) Dependency injection, warehousing, service multi-project hierarchical implementation, core permission management system

0 Asp. Net Core: permission management system (0)

1 Asp. Net Core project practice-permission management system (1) Use AdminLTE to build a front-end

2 Asp. Net Core project practice-permission management system (2) function and entity Design

3. Asp. Net Core: permission management system (3) using PostgreSQL through EntityFramework Core

4 Asp. Net Core project practices-permission management system (4) multi-project hierarchical implementation of dependency injection, warehousing, and services

5 Asp. Net Core project practices-permission management system (5) User Logon

Github Source Code address

0 project structure

The initial purpose of writing this series is to better learn Asp. Net Core, use a small system as an exercise, and urge yourself. It may not be used in real projects in the short term, but at least through learning, I have a general understanding of Asp. Net Core, which is also a technical reserve for potential applications in the future. The idea was simple at first, that is, to complete all the work in a Web project and get a general understanding of the knowledge system of Asp. Net Core.

In the course of practice, the project of this exercise is unconsciously layered. The overall structure of the project is as follows:

/// <Summary> /// definition of the warehousing interface /// </summary> public interface IRepository {}/// <summary> /// definition of the generic warehousing interface // // </summary> /// <typeparam name = "TEntity"> entity type </typeparam> /// <typeparam name = "TPrimaryKey"> Primary Key type </typeparam> public interface IRepository <TEntity, TPrimaryKey>: IRepository where TEntity: entity <TPrimaryKey >{/// <summary> // obtain the object set /// </summary> /// <returns> </returns> List <TEntity> GetAllList (); /// <summary> /// obtain the object set based on the lambda Expression Conditions /// </summary> /// <param name = "predicate"> lambda Expression Conditions </param >/// <returns> </returns> List <TEntity> GetAllList (Expression <Func <TEntity, bool> predicate ); /// <summary> /// obtain the object based on the primary key /// </summary> /// <param name = "id"> entity primary key </param> /// <returns> </returns> TEntity Get (TPrimaryKey id ); /// <summary> /// obtain a single object based on the lambda Expression Conditions /// </summary> /// <param name = "predicate"> lambda Expression Conditions </param >/// <returns> </returns> TEntity FirstOrDefault (Expression <Func <TEntity, bool> predicate ); /// <summary> /// add entity /// </summary> /// <param name = "entity"> entity </param> /// <returns> </returns> TEntity Insert (TEntity entity ); /// <summary> /// Update an object /// </summary> /// <param name = "entity"> entity </param> TEntity Update (TEntity entity); /// <summary> /// add or update an object /// </summary> /// <param name = "entity"> entity </param> TEntity InsertOrUpdate (TEntity entity ); /// <summary> /// Delete entity /// </summary> /// <param name = "entity"> object to be deleted </param> bool Delete (TEntity entity ); /// <summary> /// Delete an object /// </summary> /// <param name = "id"> entity primary key </param> bool Delete (TPrimaryKey id );}

This exercise project uses a primary key of the Guid type. For ease of use, it inherits an interface that defines a primary key type as Guid.

/// <Summary> /// default Guid primary key type warehousing // </summary> /// <typeparam name = "TEntity"> </typeparam> public interface IRepository <TEntity>: IRepository <TEntity, Guid> where TEntity: Entity {}
1.1 Definition of user management warehouse Interface

Without special operations, our basic interfaces can basically meet the needs of adding, deleting, modifying, and querying all types of entities. For an object-specific operation, the operation interface must be defined separately. For example, we will implement the user login verification function, that is, provide the user name and password to verify whether the user exists and whether the user name and password are correct. For such specific requirements, we define a user-managed warehousing interface for the user entity.

Create an interface named "IUserRepository" in the "IRepositories" folder, which defines only one method to check whether a user exists as our final test interface.

/// <Summary> /// user management warehouse interface /// </summary> public interface IUserRepository: IRepository <User >{/// <summary> /// check whether the User exists /// </summary> /// <param name = "userName"> User name </param> /// <param name = "password"> password </param> /// <returns> the user entity is returned, otherwise, NULL </returns> User CheckUser (string userName, string password) is returned );}

/// <Summary> /// warehouse base class /// </summary> /// <typeparam name = "TEntity"> entity type </typeparam> /// <typeparam name = "TPrimaryKey"> Primary Key type </typeparam> public abstract class FonourRepositoryBase <TEntity, TPrimaryKey>: IRepository <TEntity, TPrimaryKey> where TEntity: Entity <TPrimaryKey> {// defines the data access context object protected readonly FonourDbContext _ dbContext; /// <summary> /// get the data context object instance through constructor injection // </summary> /// <param name = "d BContext "> </param> public FonourRepositoryBase (FonourDbContext dbContext) {_ dbContext = dbContext ;} /// <summary> /// obtain the object set /// </summary> /// <returns> </returns> public List <TEntity> GetAllList () {return _ dbContext. set <TEntity> (). toList ();} /// <summary> /// obtain the object set based on the lambda Expression Conditions /// </summary> /// <param name = "predicate"> lambda Expression Conditions </param >/// <returns> </returns> public List <TEntity> GetAllL Ist (Expression <Func <TEntity, bool> predicate) {return _ dbContext. set <TEntity> (). where (predicate ). toList ();} /// <summary> /// obtain the object based on the primary key /// </summary> /// <param name = "id"> entity primary key </param> /// <returns> </returns> public TEntity Get (TPrimaryKey id) {return _ dbContext. set <TEntity> (). firstOrDefault (CreateEqualityExpressionForId (id);} // <summary> // obtain a single object based on lambda Expression Conditions /// </summary> /// <param na Me = "predicate"> lambda Expression Conditions </param> // <returns> </returns> public TEntity FirstOrDefault (Expression <Func <TEntity, bool> predicate) {return _ dbContext. set <TEntity> (). firstOrDefault (predicate );} /// <summary> /// add entity /// </summary> /// <param name = "entity"> entity </param> /// <returns> </returns> public TEntity Insert (TEntity entity) {_ dbContext. set <TEntity> (). add (entity); return entity;} // <summa Ry> // Update an object /// </summary> /// <param name = "entity"> entity </param> public TEntity Update (TEntity entity) {_ dbContext. set <TEntity> (). attach (entity); _ dbContext. entry (entity ). state = EntityState. modified; return entity ;} /// <summary> /// add or update an object // </summary> /// <param name = "entity"> entity </param> public TEntity InsertOrUpdate (TEntity entity) {if (Get (entity. id )! = Null) return Update (entity); return Insert (entity );} /// <summary> /// Delete an object /// </summary> /// <param name = "entity"> object to be deleted </param> public void Delete (TEntity entity) {_ dbContext. set <TEntity> (). remove (entity );} /// <summary> /// Delete an object /// </summary> /// <param name = "id"> entity primary key </param> public void Delete (TPrimaryKey id) {_ dbContext. set <TEntity> (). remove (Get (id);} // <summary> // Save the transaction // </summary> public void Save () {_ dbContext. saveChanges ();} /// <summary> /// judgment Expression Based on primary key construction /// </summary> /// <param name = "id"> Primary Key </param> /// <returns> </returns> protected static Expression <Func <TEntity, bool> CreateEqualityExpressionForId (TPrimaryKey id) {var lambdaParam = Expression. parameter (typeof (TEntity); var lambdaBody = Expression. equal (Expression. propertyOrField (lambdaParam, "Id"), Expression. constant (id, typeof (TPrimaryKey); return Expression. lambda <Func <TEntity, bool> (lambdaBody, lambdaParam );}}

Similarly, a warehousing operation base class with a primary key type of Guid is implemented.

/// <Summary> /// the primary key is a Guid-type warehousing base class /// </summary> /// <typeparam name = "TEntity"> entity type </typeparam> public abstract class FonourRepositoryBase <TEntity>: fonourRepositoryBase <TEntity, Guid> where TEntity: Entity {public FonourRepositoryBase (FonourDbContext dbContext): base (dbContext ){}}
2.1 Implementation of user management warehouse Interface

Create a new implementation class "UserRepository" for the user management warehousing interface in the "Repositories" folder of the Fonour. EntityFrameworkCore project to implement the User check method defined in the interface.

/// <Summary> // Implementation of User-managed warehousing /// </summary> public class UserRepository: FonourRepositoryBase <User>, IUserRepository {public UserRepository (FonourDbContext dbcontext ): base (dbcontext) {}/// <summary> /// check whether the user exists /// </summary> /// <param name = "userName"> User name </param> // /<param name = "password"> password </param> // <returns> the user entity is returned, otherwise, NULL </returns> public User CheckUser (string userName, string password) {return _ dbContext. set <User> (). firstOrDefault (it => it. userName = userName & it. password = password );}}

/// <Summary> /// user management service /// </summary> public class UserAppService: IUserAppService {// user management warehouse interface private readonly IUserRepository _ userReporitory; /// <summary> /// constructor to implement dependency injection /// </summary> /// <param name = "userRepository"> storage object </param> public UserAppService (IUserRepository userRepository) {_ userReporitory = userRepository;} public User CheckUser (string userName, string password) {return _ userReporitory. checkUser (userName, password );}}4 Asp. Net Core dependency injection implementation

In the previous section, we talked about how to use the ConfigureServices method of the Startup. cs file of the Fonour. MVC Project

services.AddDbContext<FonourDbContext>(options =>options.UseNpgsql(sqlConnectionString));

Method to add the context on the database to the system service. It is at this time that the context for data access is dependency injected.

Add the following code to the ConfigureServices method to implement dependency injection for the created warehouse and service.

services.AddScoped<IUserRepository, UserRepository>();services.AddScoped<IUserAppService, UserAppService>();

Note: Asp. Net Core provides three life cycle modes:

  • TransientServiceProvider always creates a new service instance.
  • ScopedThe service instance created by ServiceProvider is saved by itself (the same request). Therefore, the service instance provided by the same ServiceProvider object is the same object.
  • SingletonAlways the same Instance Object

For data access context, we can control the lifecycle of the data access context object by using the second parameter of the reload method. The default lifecycle is Scoped.

services.AddDbContext<FonourDbContext>(options => options.UseNpgsql(sqlConnectionString), ServiceLifetime.Transient);services.AddDbContext<FonourDbContext>(options => options.UseNpgsql(sqlConnectionString), ServiceLifetime.Scoped);services.AddDbContext<FonourDbContext>(options => options.UseNpgsql(sqlConnectionString), ServiceLifetime.Singleton);

The AddTransient, AddScoped, and AddSingleton methods are provided to control the object declaration cycle for the interfaces and objects to be injected.

5 Test

We added an IUserAppService service object definition to the LoginController of the Fonour. MVC project, and provided LoginController constructor to inject dependencies into the UserAppService.

Add the call code of the IUserAppService User Check Method to the Index controller and add a breakpoint for testing.

public class LoginController : Controller{    private IUserAppService _userAppService;    public LoginController(IUserAppService userAppService)    {        _userAppService = userAppService;    }    // GET: /<controller>/    public IActionResult Index()    {        var user = _userAppService.CheckUser("admin", "123456");        return View();    }}

Run the program, go to the breakpoint, and find that the user data created in the previous section has been taken out based on the user name and password. At this point, the channels between layers of our project have been connected.

6. Conclusion

This section describes the dependency injection mechanism of Asp. Net Core. We use the dependency injection mechanism to achieve the connection between different connections through a clear multi-project hierarchy.

The next section describes how to implement user logon, including user logon verification and user interception and judgment on the Controller Action route access.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.