.netcore 定制化开发的思考和实现
今年年初进了一家新公司,进入之后一边维护老项目一边了解项目流程,为了接下来的项目重做积累点经验。
先说下老项目吧,.net fx 3.5+oracle......
在实际维护中逐渐发现,老项目有标准版、定制版两种,标准版就是一套代码,粗略计算了下,全部版本加起来有20+个版本,如果项目重做后还是依照这个模式去开发维护,估计距离猝死也不远了,并且不同版本代码的复用率极低(好吧,根本没有)。打个比方,我在标准版中发现了一个bug,需要去其他的20+版本里面都修改一遍,删库跑路了解一下。。。。
为了提升工资(偷懒),进公司没多久就在想办法,如何去提高不同项目的代码复用率,然后想起来了wtm、abp、simplcommerce这三种项目,似乎有不同项目中代码服用的地方。
wtm、abp类似,是将底层的部分controller、view封装在底层类库,然后项目最外层去使用;
simplcommerce是将所有的模块放在各个类库中,然后在主项目中集成;
(或许是我看的不够深入,欢迎指正)
这三种项目,对于我的不同项目提交代码复用率来说,不能直接起到作用,但是却提供了一种思路,我们可以将原始的标准版作为一个类库,然后在不同的项目中引用这个类库,做到绝大部分的代码复用,少部分修改。
那我们开始新建一个简化版的项目,大概的分组可以做这样
native/default作为标准版的web类库,entity是实体、service是服务,实体和服务我们暂且不说,先说明下default这个类库,这个类库就是上面所说的标准类库,让其他的tailor.custom1、tailor.custom1.https、tailor.custom2.https、tailor.custom3.https(以下称定制项目)去引用,然后再各自的项目中可以个性化修改
default类库的csproj文件做适当的修改
<project sdk="microsoft.net.sdk.web"> <propertygroup label="globals"> <sccprojectname>sak</sccprojectname> <sccprovider>sak</sccprovider> <sccauxpath>sak</sccauxpath> <scclocalpath>sak</scclocalpath> </propertygroup> <propertygroup> <targetframework>netcoreapp3.1</targetframework> <outputtype>library</outputtype> </propertygroup> ... </project>
借鉴wtm中使用项目对web类库的引用,定制项目主要引用是通过startup=>configureservices=>addframeworkservice和startup=>configureservices=>useframeworkservice将标准版default中的controller和view添加到我们的定制项目中,我们就可以进行使用了。
想到这个,我们大概可以在定制项目中调用所有的标准版功能了。
但是我们如果想在定制项目中对标准版某个controller的某个action进行修改该怎么办?
1.我首先想到的是在个性化项目中写一个同名的controller,然后这个controller继承自默认版本的对应controller,来达到重写的目的,但是这个惯性思维陷入误区了,mvc对于controller的控制不和普通的type继承一样,如果同名controller存在,则会报错。。。在运行时我们可以判断出是哪个action不同,但是无法通过emit来进行修改,所以这种办法不可以。
2.第一种办法不行,那么我们是否可以对于同名controller进行名称上的修改,比如homecontroller在tailor.custom1中修改未tailorcustom1homecontroller,然后利用路由进行重定向?结果发现路由重定向,要么自定义一个路由中间件(求大佬给解决办法,我不会。。),要么在请求进入的时候对请求进行重定向(这种重定向就是对httpcontext.request.path进行特殊判断和处理,符合条件的进行重定向,但是可能会有很大的问题)
3.使用版本控制的思路,这个似乎可以,我们将标准版default中所有的都作为版本1.0,然后定制化作为2.0,在请求进入的时候,将请求头添加一个version,如果mvc找不到这个version的controller或者action,会自动转到默认的1.0版本中
具体实现代码地址:https://github.com/wangpengzong/tailor
native/default是标准版网站类库
tailor.custom* 是定制化网站,可以在此路径下继承native/default的对应controller,利用overvide对需要重写的action进行重写,不需要重写的不进行overvide即可,或者对cshtml进行重写,不需要重写的不在对应路径下增加cshtml文件即可