ASP.NET Core - 利用Windsor Castle实现通用注册
问题引入
在ASP.NET Core - 依赖注入这篇文章里面,我们知道了如何利用ASP.NET Core原生的容器来实现依赖注入的,那我们为什么要替换掉默认的 IoC容器呢?从ASP.NET Core - 依赖注入这篇文章来看的话,默认的IoC容器对于一些小型的项目基本够用,它提供了基本的AddXXXX方法来绑定实例关系,但是对于大型项目来说,还是挺困难的,大型的项目需要的是通用的注册,不可能手动添加每个对象的解析关系,这才是我们面临的痛点。
解决方案
这里不打算详解Castle的内容,专注于如何使用Castle实现通用注册和替换掉原生的IoC容器。
首先我们需要一个通用的注册类,是基于我们自定义规则来注册的,比如说在程序集中满足继承ITransientDependency的话我们会给实现类注册为Transient的生命周期,ISingletonDependency会给实现类注册为Singleton的生命周期。
/// <summary>
/// 通过输入的程序集来注册满足约定的所有类
/// </summary>
public class BasicConventionalRegistrar
{
private readonly WindsorContainer _container = new WindsorContainer(); /// <summary>
/// 注册程序集中满足约定的类
/// </summary>
/// <param name="assemblies"></param>
/// <returns></returns>
public WindsorContainer RegisterAssembly(List<Assembly> assemblies)
{
foreach (var assembly in assemblies)
{
//Transient
_container.Register(
Classes.FromAssembly(assembly)
.IncludeNonPublicTypes()
.BasedOn<ITransientDependency>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleTransient()
); //Singleton
_container.Register(
Classes.FromAssembly(assembly)
.IncludeNonPublicTypes()
.BasedOn<ISingletonDependency>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleSingleton()
);
}
return _container;
}
}
如何使用?
有个这个类,我们需要把各个程序集中满足条件的类注册进来,首先需要在NuGet下载Castle.Windsor.MsDependencyInjection包,并且在ConfigureServices方法中修改返回类型为IServiceProvider,然后通过RegistBasicConventionalRegistrar把各个需要注册的程序集注册进来。
这里需要非常注意的是,在ASP.NET Core - 依赖注入这篇文章里面提到ConfigureServices是可以返回一个IServiceProvider对象的,这里是基于这个返回对象引入了第三方容器替换。
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc(); var container = RegistBasicConventionalRegistrar();
//替换容器
return WindsorRegistrationHelper.CreateServiceProvider(container, services);
} //通用规则注册
private WindsorContainer RegistBasicConventionalRegistrar()
{
var list = new List<Assembly>();
list.Add(Assembly.GetExecutingAssembly ());
list.Add(yourProjectAssembly);
...
return BasicConventionalRegistrar.RegisterAssembly(list);
}
按程序集注册
上面的代码我们可以看到,主要是利用了WindsorRegistrationHelper这个类实现注册到Windsor Castle容器中,且核心方法RegistBasicConventionalRegistrar是基于程序集注册的。在正式的应用场景中,我们是非常可能需要把多个程序集都按约定来注册的,个人建议的做法是,在每个需要注册的程序集中添加一个标志该程序集的基类,比如说我会在Service这个程序集中添加一个IServiceBase接口,这样就可以通过typeof(IServiceBase).Assembly获取到这个程序集进而用来注册
按约定进行继承
在我们的service业务层(或者任何需要注册的地方),把需要注册的类继承通用注册接口(生命周期自己选择)
public interface IPostBlogService : ITransientDependency
{
Result Post(BlogDto dto);
} public class PostBlogService : IPostBlogService
{
public Result Post(BlogDto dto)
{
//todo: post this blog
}
}
实例解析
在任何需要的地方通过构造方法注入(或属性注入)
[ApiController]
[Route("api/Blog")]
public class BlogController: Controller
{
public readonly IBlogService _blogService;
public BlogController(IBlogService blogService)
{
_blogService = blogService;
} [HttpPost]
public Result PostBlog(BlogDto dto)
{
return _blogService.Post(dto);
}
}
这样就实现了完整的通用注册解析流程,在实际应用中,个人建议把这些通用解析方法放在基础设施模块,因为这样不仅本项目可以用,还可以把基础设施抽离出来作为基础框架,通过nuget使用版本控制作为公司所有项目的通用注册础框架。
让我知道如果你有更好的想法或建议!
ASP.NET Core - 利用Windsor Castle实现通用注册的更多相关文章
- asp.net core利用DI实现自定义用户系统,脱离ControllerBase.User
前言 很多时候其实我们并不需要asp.net core自带的那么复杂的用户系统,基于角色,各种概念,还得用EF Core,而且在web应用中都是把信息存储到cookie中进行通讯(我不喜欢放cooki ...
- 基于ASP.Net Core开发的一套通用后台框架
基于ASP.Net Core开发一套通用后台框架 写在前面 这是本人在学习的过程中搭建学习的框架,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 知其然,知其所以然,并非重 ...
- [翻译] ASP.NET Core 利用 Docker、ElasticSearch、Kibana 来记录日志
原文: Logging with ElasticSearch, Kibana, ASP.NET Core and Docker 一步一步指导您使用 ElasticSearch, Kibana, ASP ...
- ASP.NET Core扩展库之Http通用扩展
本文将介绍Xfrogcn.AspNetCore.Extensions扩展库对于Http相关的其他功能扩展,这些功能旨在处理一些常见需求, 包括请求缓冲.请求头传递.请求头日志范围.针对HttpClie ...
- ASP.NET Core Identity 实战(2)——注册、登录、Claim
上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...
- ASP.NET Core 利用中间件支持跨域请求
方法1: 在Startup的ConfigureServices()中添加services.AddCors()在Startup的Configure()中添加app.UseCors(); 保证其在app. ...
- ASP.NET Core利用拦截器 IActionFilter实现权限控制
“麦荻网教系统”采用了前后端代码分离的架构,即“Miidy.Cloud.Console”站与“Miidy.Cloud.Manage”站(两个前端站)同时通过web api的方式调用“Miidy.Clo ...
- ASP.NET Core[源码分析篇] - Startup
应用启动的重要类 - Startup 在ASP.NET Core - 从Program和Startup开始这篇文章里面,我们知道了Startup这个类的重要性,它主要负责了: 配置应用需要的服务(服务 ...
- asp.net core 3.x 通用主机原理及使用
一.前言 只是讲asp.net core 3.x通用主机的大致原理,这些东西是通过查看源码以及自己根据经验总结得来的,在文章中不会深入源码,因为个人觉得懂原理就晓得扩展点,后期碰到有需求的时候再仔细去 ...
随机推荐
- 设计一个卖不同种类车的4s店
# 定义奔驰车类 class BenchiCar(object): # 定义车的方法 def move(self): print('---奔驰车在移动---') def stop(self): pri ...
- compose合并函数依次执行 - 来源redux
function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1 ...
- linux下安装nginx与配置
linux系统为Centos 64位 第一步:从http://nginx.org/download/上下载相应的版本(或者wget http://nginx.org/download/nginx-1. ...
- Java历程-初学篇 Day01初识java
HelloWorld!!!!! 一,第一个java程序的构成 1,外层框架 class 后面的类名必须与文件名相同 起名方法:1)构成只能有_ $ 字母 数字 2)数字不能开头 3)首字母必须大写 4 ...
- spring security oauth2 jwt 认证和资源分离的配置文件(java类配置版)
最近再学习spring security oauth2.下载了官方的例子sparklr2和tonr2进行学习.但是例子里包含的东西太多,不知道最简单最主要的配置有哪些.所以决定自己尝试搭建简单版本的例 ...
- 系列博文-Three.js入门指南(张雯莉)-静态demo和three.js功能概览
一:一个最简单的静态DEMO //body加载完后触发init() //WebGL的渲染是需要HTML5 Canvas元素的,你可以手动在HTML的<body>部分中定义Canvas元素, ...
- git学习(持续踩坑中🤣)
https://segmentfault.com/q/1010000002457936 常见指令: 一.创建版本库 $ mkdir learngit 创建文件夹 $ cd learngit 进入文件夹 ...
- JAVA API操作hbase1.4.2
package com.quyf; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; imp ...
- ubuntu 16.04启用root用户方法
1.使用:sudo passwd root设置root的密码,如下图所示: 2.使用su root来测试是否可以进入root用户,如果出现#说明已经设置root用户的密码成功,如下图所示:
- Python字符编码与转码
字符编码与转码 注: 该图转自 http://www.cnblogs.com/luotianshuai/p/5735051.html. Python2 解码,编码 #Python2 #-*- codi ...