Microsoft.AspNet.Identity简介

Microsoft.AspNet.Identity是微软在MVC 5.0中新引入的一种membership框架,和之前ASP.NET传统的membership以及WebPage所带来的SimpleMembership(在MVC 4中使用)都有所不同。

Microsoft.AspNet.Identity是符合微软开放Owin标准里面Security标准的一种实现。且在MVC 5中默认使用EntityFramework作为Microsoft.AspNet.Identity的数据存储实现。

从Microsoft.AspNet.Identity里面,我们其实可以看出微软所采用的一种MVC的分层架构;或许这种分层架构我们可以学习并应用在自己的开发当中。

Microsoft.AspNet.Identity从Preview到RC到RTM一直都有变化,下面我当然以RTM的结构来简单讲解一下这种值得借鉴的参考分层架构。

参考分层架构

首先要说明的是,我上面提到的分层架构不是指MVC本身的分层,而是指Controller与Data之间的分层(与耦合方式)。

你在VS2013中创建一个带有独立账号管理的MVC项目后,默认就有一个用于登录、注册的AccountController,通过这个Controller,我们就可以顺藤摸瓜一窥Microsoft.AspNet.Identity的真容。

我们先来看一个类图:

从上图中,我们可以看到如下类以及他们的关系:

AccountController

账号管理的Controller。具有一个名为UserManager的属性,这个属性的类型为UserManager<TUser>。并暴露一个名为AuthenticationManager的属性,类型为IAuthenticationManager。

Controller顾名思义只起到控制器的作用,就是把M和V结合在一起,而如何得到M如何处理M得到什么样的M,就是业务逻辑的事情。

业务逻辑你可以很dirty的写中Controller里面,也可以像Microsoft.AspNet.Identity一样把用户管理的业务逻辑都封装到UserManager中。

把 登录和注销逻辑保证到AuthenticationManager中,当然AuthenticationManager实际上是一个来自于Owin的接口 IAuthenticationManager,通过这样的设定,Microsoft.AspNet.Identity就和Owin的Security兼 容了。不过我这里不会详细讲Owin的Security的。

AccountController提供了两个构造方法:

  1. 一个默认的:

     public AccountController()
    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
    {
    }
  2. 一个可以传入UserManager实例的:
    public AccountController(UserManager<ApplicationUser> userManager)
    {
    UserManager = userManager;
    }

UserManager<TUser>(Microsoft.AspNet.Identity,Microsoft.AspNet.Identity.Core.dll)

这些一个泛型的用户管理业务逻辑的类。泛型的原因是因为要支持Profile信息的扩展,这里也不详细介绍。 UserManager<TUser>仅仅是封装了业务处理的逻辑,并没有去实现数据如何处理的代码。相关代码都交给 IUserStore<TUser>。

UserManager<TUser>只提供了一个接受IUserStore<TUser>实例的构造函数:

public UserManager(IUserStore<TUser> store);

IUserStore<TUser>(Microsoft.AspNet.Identity,Microsoft.AspNet.Identity.Core.dll)

这个接口抽象了用户数据如何处理的逻辑。但是具体实现要交给和具体数据访问技术相关的实现。从AccountController的默认构造函数 中,我们可以看到给UserManager传入了一个IUserStore<TUser>的实现 UserStore<ApplicationUser>。

UserStore<TUser>(Microsoft.AspNet.Identity.EntityFramework,Microsoft.AspNet.Identity.EntityFramework.dll)

这个类实现IUserStore<TUser>接口以及一系列相关接口(比 如:IUserLoginStore<TUser>等)。这个类实际上为UserManager提供了对用户真实数据的访问能力,在这里,是 把用户数据通过EntityFramework来存储和获取的(而数据实际是保存中SQL Server的各类版本中还是保存在MySQL中,就又取决于EntityFramework的数据库驱动适配层了,和这个分层架构实际上无关了)。而由 于UserStore<TUser>是依赖于EntityFramework来存取数据的,所以他的构造函数也接受DbContext作为参 数:

public UserStore(DbContext context);

虽然DbContext是一个通用的类,不过从AccountController的构造函数中,我们还是可以看到实际上传入的是一个继承于IdentityDbContext<TUser>的DbContext。

IdentityDbContext<TUser>(Microsoft.AspNet.Identity.EntityFramework,Microsoft.AspNet.Identity.EntityFramework.dll)

这是一个包含了Code-First模型定义的DbContext了,其中当然定义了Users这个IDbSet<TUser>,所以对用户数据的操作最终都是由这个DbContext完成的。

类似架构的讲解

这里的这篇文章(http://www.codeproject.com/Articles/207820/The-Repository-Pattern-with-EF-code-first-Dependen)其实就讲解了这种类似的分层架构。

其中,文章中提到的IRepository(特定于某个领域类的ICategoryRepository)就是IUserStore,而 CategoryRepository就类似于UserStore<TUser>,而CatalogService和UserManager 比较接近。

通过依赖注入充分利用这种架构的灵活性

从上面的这些类的构造函数中,我们还可以看到以各种重要特点,就是好几个类都具有参数构造函数,这样的设计不得不说是为了依赖注入而准备了。所以,我也简单讲解一下如何用Unity来进行简单的依赖注入(其他依赖注入框架用法类似)。

首先,通过NuGet来添加Unity和Unity.Mvc这两个包。

添加以后,在App_Start文件夹里面会出现两个文件:UnityConfig.cs和UnityMvcActivator.cs,在UnityConfig.cs文件中的RegisterTypes函数中,添加如下两行代码:

            container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
container.RegisterType<DbContext, ApplicationDbContext>();

就可以非常简单地利用Unity来把相关实现类注入进去。所以在这里,你可以把自己实现的UserStore注入进去,假设你的UserStore用到的是类似MongoDB这样的NoSQL的话,那么你同样也可以把MongoDB的session注入进去。

通过定义接口,基于接口实现,并在相关类上暴露具有参数的构造函数,可以实现各个分层实现之间的松耦合,并通过依赖注入来极大的增加代码的灵活性。

总结

在我们的实际项目开发中,如果为了获得灵活性完全可以照搬这种模式;当然,如果只是想快速实现一个原型或者就是一个小项目的话,那么在Controller里面直接调用DbContext也没有什么大不了的。

update-2013-11-04 关于ASP.NET Identity的更多信息,可以参考官方文档:http://www.asp.net/identity/overview/getting-started

http://www.cnblogs.com/redmoon/p/3393264.html

从Microsoft.AspNet.Identity看微软推荐的一种MVC的分层架构的更多相关文章

  1. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  2. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现,aspnet.identity

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  3. Asp.net Identity 系列之 怎样修改Microsoft.AspNet.Identity.EntityFramework.IdentityUser 的 Id 字段的数据类型

    这篇博客我们来学习如何将AspNetUsers 表的Id 字段 的类型由nvarchar(128) 改为Int 并且子增长 1.为什么要修改 如果你运行过 Asp.net mvc 示例项目,你好会发现 ...

  4. 跟Microsoft.AspNet.Identity学习哈希加盐法

    什么是哈希加盐法? 废话少说:对于MD5这种加密算法,同样的密码每次加密后得到的密文是一样的,所以黑客可以利用已知的密码库(彩虹库)对目标数据库密文进行对比进行攻击. 怎样解决:哈希加盐法,以下是网上 ...

  5. Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; ...

  6. Microsoft.AspNet.Identity 的简单使用

    要完成一个简单的注册,登陆,至少需要实现Identity中的3个接口 IUser IUserStore<TUser> : IDisposable where TUser : IUser I ...

  7. MVC5中 在更新 Microsoft.Aspnet.Identity 后编译器错误

    环境:vs2013预览版chs,我试着创建vb.net web应用,从对话框中选择MVC和WebAPI.编译ok了.通过NuGet管理器更新了Microsoft.Aspnet.Identity.Cor ...

  8. 命名空间“Microsoft.AspNet”中不存在类型或命名空间名“Mvc”

    问题: 错误 CS0234 命名空间"Microsoft.AspNet"中不存在类型或命名空间名"Mvc"(是否缺少程序集引用?) 解决方案: 打开文件夹 Us ...

  9. Microsoft.AspNet.Identity: UserID用整型数据表示, 而不是GUID

    第一篇:  这个好像不太好 http://stackoverflow.com/questions/19553424/how-to-change-type-of-id-in-microsoft-aspn ...

随机推荐

  1. GBDT和RF的区别

    去XX公司实习的时候,被问过,傻逼的我当时貌似都答错了,原谅全靠自学的我,了解甚少 RF随着树的增加不会过拟合 GBDT随着树的增加会过拟合 RF还会对特征进行random,例如特征的个数m=sqrt ...

  2. OneThink学习笔记02----数据字典(即OneThink项目数据库里的表及其字段)

    action 字段 类型 注释 id int(11) unsigned 自增主键 name char(30) 行为唯一标识 title char(80) 行为说明 remark char(140) 行 ...

  3. jquery插件-表单验证插件

    JQuery 插件概述: 插件(plugin)也被成为扩展,是一种遵循一定规范的应用程序编写出来的程序,JQuery有大量 现成的插件. 一句话,JQuery插件就是别人依照Jquery官方规范写好的 ...

  4. [NOIP2014] 提高组 洛谷P2312 解方程

    题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, m ] 内的整数解(n 和m 均为正整数) 输入输出格式 输入格式: 输入文件名为equation .i ...

  5. grid列的值格式化

    //列格式化 waf.defineCustomeClass("cellformatter.ratioFomatter", cellformatter.defaultFormatte ...

  6. squid节点添加新域名测试

    squid节点添加新域名 测试是否缓存成功 #!/bin/bash #-- clear #清屏 方便输出结果观看 url=* #需要测试的url array_node[]="*" ...

  7. 数据结构算法C语言实现(十九)--- 5.5&5.6&5.7广义表

    一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一 ...

  8. [Android]GOF23种设计模式 & Android中的设计模式

    GOF23种设计模式 设计原则: 1. 单一职责原则(SRP):就一个类而言,应该仅有一个引起它变化的原因 2. 开放-封闭原则(OCP):软件实体(类.模块.函数等)应该可以扩展,但是不可修改.即对 ...

  9. python 中的map(), reduce(), filter

    据说是函数式编程的一个函数(然后也有人tucao py不太适合干这个),在我看来算是pythonic的一种写法. 简化了我们的操作,比方我们想将list中的数字都加1,最基本的可能是编写一个函数: I ...

  10. Axure7.0中文汉化语言包下载 axure汉化包

    Axure RP Pro 7.0 正式版 (兼容 6 版) 简体中文语言包 支持 Axure RP Pro 正式版 当前最新版本 7.0.0.3142 废话不多说,直接给下载地址: Axure7.0中 ...