1. 程式人生 > >登錄註冊的小項目對比.Net Core與 .Net Framework的一些區別

登錄註冊的小項目對比.Net Core與 .Net Framework的一些區別

lte 版本 ota .net valid row start net microsoft

一、需求:

1、功能只有登錄、註冊。

二、架構:

1、分別為

UserSys.IServices:主要有實體和對實體的配置,還有對實體的操作接口

UserSys.Services :主要是對自IService層中的接口實現

UserSys.DTO :主要是我們Web層中需要什麽實體就給傳遞什麽實體

UserSys.Common:一些通用的組件封裝到該類庫中

UserSys.Web:Asp.Net MVC

技術分享

2、Web層采用Asp.Net MVC

3、數據庫訪問通過EF

三、具體實現

1、寫User實體

public class User
    {
        public long Id { get; set; }
        public string PhoneNum { get; set; }
        public string PasswordHash { get; set; }
        public bool IsDeleted { get; set; }
    }

分別通過Nuget安裝EF

.Net Freamwork中 Install-Package EntityFramework

.Net Core中 Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 2.0.0 一定要寫上版本號

2、對實體中的字段進行配置 UserConfig

.Net Freamwork中 UserConfig需要繼承EntityTypeConfiguration<User>

    public class UserConfig : EntityTypeConfiguration<User>
    {
        public
UserConfig() { this.ToTable("Users"); this.Property(o => o.PhoneNum).HasMaxLength(200).IsRequired(); this.Property(o => o.PasswordHash).HasMaxLength(200).IsRequired(); } }

.Net Core中內置了IEntityTypeConfiguration

public class UserConfig : IEntityTypeConfiguration<User>
    {
        public void Configure(EntityTypeBuilder<User> builder)
        {
            builder.ToTable("Users");
            builder.Property(u => u.PasswordHash).IsRequired().HasMaxLength(200);
            builder.Property(u => u.PhoneNum).IsRequired().HasMaxLength(200);            
        }
    }

3、封裝一個MyDbContext

.Net Freamwork中我們繼承自DbContext ,並重寫該OnModelCreating方法

public class MyDbContext : DbContext
        {
                     
            public MyDbContext() : base("constr")   //base中的參數為數據庫的連接字符串
            {

            }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                //這樣就得到當前運行的
                //這句話的意思就是  加載我們這句話所在的程序集加載所有的繼承自EntityTypeConfiguration 為模型配置類。
                modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
            }

            public DbSet<Users> User { get; set; }
        }

下面這段代碼代表從這句話所在的程序集加載所有的繼承自 EntityTypeConfiguration 為模型配置類

     modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());

.Net Core中 同樣也是該類繼承DbContext,但是需要分別重寫OnConfiguring和OnModelCreating方法

public class MyDbContext:DbContext
    {
        public DbSet<Users> Users { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            var builder =
                new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())//SetBasePath設置配置文件所在路徑
                .AddJsonFile("appsettings.json");
            var configRoot = builder.Build();
            var connString =
                configRoot.GetSection("db").GetSection("ConnectionString").Value;
            optionsBuilder.UseSqlServer(connString);
        }
        

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
//這段代表表示,加載我們當前實體Users類所有的程序集 Assembly asmServices
= Assembly.Load(new AssemblyName("UserSys.Services")); modelBuilder.ApplyConfigurationsFromAssembly(asmServices); } }

註意:

1)、 .Net Core中沒有內置像EF 中的modelBuilder.Configurations.AddFromAssembly()方法 ,但是不用擔心,楊老師已經給我們封裝了一個和EF中相同作用的

Nuget包,我們只需要安裝就行了https://www.nuget.org/packages/RuPeng.EFCore.Ext

2)、.Net Core中的數據庫連接等信息以鍵值對的形式是放在 json文件中的,與.Net Framework中不同,.Net Framework中是配置為Web.Config中的

技術分享

4、開始寫對Users類的操作接口IUserService .Net Core和.Net FrameWork中是相同的

    public interface IUserService
    {
        void Add(string phoneNum, string password);
        UserDTO GetByPhoneNum(string phoneNum);
        bool CheckLogin(string phoneNum, string password);
    }

5、寫實現類UserService

   public class UserService : IUserService
    {
        public void AddNew(string phoneNum, string password)
        {
            using (MyDbContext ctx = new MyDbContext())
            {
                if(ctx.Users.Any(u => u.PhoneNum == phoneNum))
                {
                    throw new ApplicationException("手機號已經存在");
                }
                User user = new User();
                user.PasswordHash = MD5Helper.Md5(password);
                user.PhoneNum = phoneNum;
                user.IsDeleted = false;
                ctx.Users.Add(user);
                ctx.SaveChanges();
            }
        }

        public bool CheckLogin(string phoneNum, string password)
        {
            using (MyDbContext ctx = new MyDbContext())
            {
                User user = ctx.Users.SingleOrDefault(u => u.PhoneNum == phoneNum);
                if(user==null)
                {
                    return false;
                }
                string inputPwdHash = MD5Helper.Md5(password);
                return user.PasswordHash == inputPwdHash;
            }
        }

        public UserDTO GetByPhoneNum(string phoneNum)
        {
            using (MyDbContext ctx = new MyDbContext())
            {
                User user = ctx.Users.SingleOrDefault(u => u.PhoneNum == phoneNum);
                if(user==null)
                {
                    return null;
                }
                return new UserDTO { Id=user.Id,PasswordHash=user.PasswordHash,PhoneNum=phoneNum};
            }
        }
    }

到這就剩下Web層的登錄和註冊了,So Easy,所以就不寫具體怎麽寫了。

需要說下的是:依賴註入的問題:

1、.Net FrameWork中我們通過IOC對類進行註入,怎麽註入自行百度,方法很多,我主要說下.Net Core中怎麽註入

因為在.Net Core中已經內置了IOC 容器 ,不再需要 autofac 等,當然 autofac 也是支持.net core的( http://www.open-en.com/lib/view/open1454127071933.html)。

內置 IOC 是通過構造函數註入,而不是屬性註入。

2、.Net Core中有內置的IOC有三種生命周期,我們采用Singleton 的方式註入,ingleton 生命能夠周期服務在第一被請求時創建,在後續的每個請求都會使用同一個實例。

具體實現: 在Controller中使用構造函數註入(不是屬性註入)

1)、首先需要在UserSys.IService層中,寫一個通用的接口,該接口中不需要定義任何的方法,但是該類庫中需要用到的接口都需要繼承自IServiceTag接口

技術分享

2)、如果我們註入單個類的話,可以直接在Startup.cs中的ConfigureServices方法中,直接這樣註入

                  services.AddSingleton(typeof(IMyService),typeof(MyService)); 

但是如果我們有多個接口需要註入呢?我們需要封裝一個方法來實現,就是通過我們下面的這樣,通過反射來實現

public void ConfigureServices(IServiceCollection services)
        {
            //Filter
            services.AddMvc(options=> {
                options.Filters.Add(new ModelStateValidationFilter());
            });
            services.AddSession();

            //註冊服務和實現類            
            Assembly asmServices = Assembly.Load("UserSys.Services");
            var serviceTypes = asmServices.GetTypes().Where(t => t.IsAbstract == false && typeof(IServiceTag).IsAssignableFrom(t));
            foreach(var serviceType in serviceTypes)
            {
                var intfTypes = serviceType.GetInterfaces()
                    .Where(t => typeof(IServiceTag).IsAssignableFrom(t));
                foreach (var intfType in intfTypes)
                {
                    services.AddSingleton(intfType, serviceType);
                }
            }
        }

3)、在需要用到該接口的實現方法的地方,我們只需要通過構造函數的形式註入就行了

    public class HomeController : Controller
    {
        private IUserService userService;
        public HomeController(IUserService userService)
        {
            this.userService = userService;
        }
    }

學習.Net 請到如鵬網

登錄註冊的小項目對比.Net Core與 .Net Framework的一些區別