ASP.NET MVC 5、Identity、Unity容器解决方案架构
ASP.NET MVC 5, Identity, Unity container solution architecture
假设一个 Web 项目由 ASP.NET MVC 5 和 OWIN/Identity 成员组成。 IoC 是用 Unity 完成的。现在一切都在一个项目中。
问题:将MVC、Identity和IoC分离到独立的项目中并将Identity封装到一些IAccountService中以供Unity在MVC项目中解析是否有意义?
这个问题好像挺傻的,不过我的橡皮鸭不知为何一直保持沉默,有猜到吗?
我想达到的目标是这样的
ASP.NET MVC (OWIN) --> IoC (Unity) --> AccountServiceImpl --> Identity
MVC、IoC --> 合同 (IAccountService)
其中 --> 是项目引用
我需要它能够更改 IoC 容器,我还需要通过接口从其他项目访问身份数据
是的,将您的解决方案分成较小的项目是安全的,例如 MVC、Identity 和 IoC。
至少,这是我的简短回答。
有意义吗?长答案有点复杂。在解决解决方案和项目架构之前,我已经回答了一些类似的问题:
- where should the interfaces be defined?
- Where should I put automapper code?
在上面的回答中,我解释了
[...] I have a typical structure like this:
- MyProject.Core
- MyProject.Domain
- MyProject.DependencyInjection
- MyProject.Infrastructure
- MyProject.Web
- MyProject.Tests
Jeffrey Palermo encourages the use of Onion Architecture. In part 4 of his article on Onion Architecture, Jeffrey provides an example solution 结构如下
- 核心
- 基础设施
- 集成测试
- UI
- 单元测试
然而,Jimmy Bogard有点不同意我和我的方法。
在 Evolutionary Project Structure 中,Jimmy 解释道:
I used to care quite a bit about project structure in applications. Trying to enforce logical layering through physical projects, I would start off a project by defaulting to building an app with at least two projects, if not more.
事实上,Jimmy 将他以前首选的解决方案架构风格描述为与我上面提到的风格相似。
吉米进一步说 "deciding about project structure is a waste of time and energy"。他实际上更喜欢更简单的解决方案结构。也就是说,很少。
尽管吉米确实通过以下方式澄清了他的立场:
I have absolutely nothing against layered software design. Using project structure to do so is a waste of time if you only have 1 app you're deploying [...]
(强调我的)
如果您有其他应用程序需要引用您的 MVC 解决方案的各个方面,将它们拆分到它们自己的项目中可能非常有意义,这样您就可以轻松地引用它们。
我认为我们应该得出的结论是:
解决方案架构不是规则或法律。在有意义的地方分离项目。
确保您的解决方案易于维护且易于被他人理解。不要使您的解决方案过于复杂。
我会为 Rowan 的出色回答加上我的 0.02¢。我将详细介绍实际的身份实施。
就 ASP.Net 身份框架而言 - 将其从 MVC 项目中移出到更高(或更低,取决于您放置它的方式)的固定层可能有点棘手。我很确定您希望在域层中有 ApplicationUser
对象。但是 ApplicationUser
取决于 IdentityUser
,后者取决于 Identity.EntityFramework
,取决于 EntityFramework
。将 EF 添加到您的域项目可能会稍微违反 Onion Architecture 的规则。
另外 ApplicationUserManager
Identity 框架非常庞大(就方法数量而言)并且还依赖于 EF。因此将它隐藏在界面后面可能会很棘手。
所以你真的有 2 个选择:
- 尝试将 EF 添加到您的域项目中,并在您的域层中包含
ApplicationUser
和 ApplicationUserManager
classes。出于多种原因,不要将 UserManager
包装在界面中。
- 以不同的方式进行攻击,将所有身份信息留在 MVC 层中,确定需要从域层执行的非常小的一组操作,并在
ApplicationUserManager
之上添加一个微型接口。
我在不同的项目中都尝试过这两种方法,并且都同样有效。我尝试在 ApplicationUserManager
之上添加接口但失败了 - 主要是因为 class 的大小,而且它旨在以异步方式工作并且有同步包装器。同步包装器不适用于您的界面 - 因为强类型。
我写了一篇关于层分离的文章blog-post about applying DI to Identity framework and there is a discussion in the comments - 看看有什么想法。
假设一个 Web 项目由 ASP.NET MVC 5 和 OWIN/Identity 成员组成。 IoC 是用 Unity 完成的。现在一切都在一个项目中。 问题:将MVC、Identity和IoC分离到独立的项目中并将Identity封装到一些IAccountService中以供Unity在MVC项目中解析是否有意义? 这个问题好像挺傻的,不过我的橡皮鸭不知为何一直保持沉默,有猜到吗?
我想达到的目标是这样的
ASP.NET MVC (OWIN) --> IoC (Unity) --> AccountServiceImpl --> Identity
MVC、IoC --> 合同 (IAccountService)
其中 --> 是项目引用
我需要它能够更改 IoC 容器,我还需要通过接口从其他项目访问身份数据
是的,将您的解决方案分成较小的项目是安全的,例如 MVC、Identity 和 IoC。
至少,这是我的简短回答。
有意义吗?长答案有点复杂。在解决解决方案和项目架构之前,我已经回答了一些类似的问题:
- where should the interfaces be defined?
- Where should I put automapper code?
在上面的回答中,我解释了
[...] I have a typical structure like this:
- MyProject.Core
- MyProject.Domain
- MyProject.DependencyInjection
- MyProject.Infrastructure
- MyProject.Web
- MyProject.Tests
Jeffrey Palermo encourages the use of Onion Architecture. In part 4 of his article on Onion Architecture, Jeffrey provides an example solution 结构如下
- 核心
- 基础设施
- 集成测试
- UI
- 单元测试
然而,Jimmy Bogard有点不同意我和我的方法。
在 Evolutionary Project Structure 中,Jimmy 解释道:
I used to care quite a bit about project structure in applications. Trying to enforce logical layering through physical projects, I would start off a project by defaulting to building an app with at least two projects, if not more.
事实上,Jimmy 将他以前首选的解决方案架构风格描述为与我上面提到的风格相似。
吉米进一步说 "deciding about project structure is a waste of time and energy"。他实际上更喜欢更简单的解决方案结构。也就是说,很少。
尽管吉米确实通过以下方式澄清了他的立场:
I have absolutely nothing against layered software design. Using project structure to do so is a waste of time if you only have 1 app you're deploying [...]
(强调我的)
如果您有其他应用程序需要引用您的 MVC 解决方案的各个方面,将它们拆分到它们自己的项目中可能非常有意义,这样您就可以轻松地引用它们。
我认为我们应该得出的结论是:
解决方案架构不是规则或法律。在有意义的地方分离项目。
确保您的解决方案易于维护且易于被他人理解。不要使您的解决方案过于复杂。
我会为 Rowan 的出色回答加上我的 0.02¢。我将详细介绍实际的身份实施。
就 ASP.Net 身份框架而言 - 将其从 MVC 项目中移出到更高(或更低,取决于您放置它的方式)的固定层可能有点棘手。我很确定您希望在域层中有 ApplicationUser
对象。但是 ApplicationUser
取决于 IdentityUser
,后者取决于 Identity.EntityFramework
,取决于 EntityFramework
。将 EF 添加到您的域项目可能会稍微违反 Onion Architecture 的规则。
另外 ApplicationUserManager
Identity 框架非常庞大(就方法数量而言)并且还依赖于 EF。因此将它隐藏在界面后面可能会很棘手。
所以你真的有 2 个选择:
- 尝试将 EF 添加到您的域项目中,并在您的域层中包含
ApplicationUser
和ApplicationUserManager
classes。出于多种原因,不要将UserManager
包装在界面中。 - 以不同的方式进行攻击,将所有身份信息留在 MVC 层中,确定需要从域层执行的非常小的一组操作,并在
ApplicationUserManager
之上添加一个微型接口。
我在不同的项目中都尝试过这两种方法,并且都同样有效。我尝试在 ApplicationUserManager
之上添加接口但失败了 - 主要是因为 class 的大小,而且它旨在以异步方式工作并且有同步包装器。同步包装器不适用于您的界面 - 因为强类型。
我写了一篇关于层分离的文章blog-post about applying DI to Identity framework and there is a discussion in the comments - 看看有什么想法。