基于Autofac, Castle.DynamicProxy的动态WCF解决方案(原创)
本方案解决了下面3个主要的问题:
1、减少配置,为了避免每次新增service都需要去修改配置文件,包括服务器端跟各个客户端的。
2、能够使用函数重载,泛型函数,以及泛型类。
3、使项目能够快速地在wcf与直接调用dll之间切换。
整个解决方案分为四块内容:1、客户端,2、契约层,3、服务端,4、实现层
1、客户端:只能看到契约层,而看不到具体的实现;但也可以通过直接引用实现层,从而脱离wcf(需要修改工厂方法,也可以改进一下,通过配置文件来做这个事情,但这个不是本解决方案的重点,有兴趣的可以自己去实现)。
2、契约层:包含DTO对象模型跟各个服务接口
3、服务端:能看到契约层跟实现层
4、实现层:使用Autofac跟Castle.DynamicProxy进行IOC跟AOP(动态代理中的拦截器)
为解决第一个问题,早些年,已有人通过只暴露WCF的一个服务,而向该服务传递类名,函数名,参数数组来解决这一问题,但是用字符串在我看来实在是不太好,谁能保证自己在编码的时候不会把字符串给写错呢,而且万一需要更改服务名,vs的代码重构机制也处理不了字符串。所以我觉得利用接口,应该是最好的解决方案,但问题是谁又能在不知道具体的实现类的情况下,而针对接口凭空实例化出来一个对象呢。答案是有的,用Emit指令,不过Emit指令实在是有点难。此时我又想到了单元测试中常用的Rhino Mocks跟moq框架,便去查看了它们的源代码,我发现其中一个用的.net自带的真实代理(RealProxy),另外个用的是Castle.DynamicProxy,个人比较喜欢Castle.DynamicProxy,就用了它的CreateInterfaceProxyWithoutTarget,然后在自定义的拦截器中去调用实际的WCF服务,将返回回来的值设置给invocation.ReturnValue。
并且针对方法中的传引用的参数,进行了处理,使其能够对传引用的参数进行赋值。
下图为整个解决方案的结构:
测试的接口:
public interface IMyTest
{
int Test1();
void Test2();
int Test3(int value);
TestModel Test4(ref TestModel T);
void Test5(TestModel T);
void Test6(out int value);
void Test7(ref int value);
int Test8(int value = );
int Test9(int value1 = , int value2 = );
int Test10(params int[] values);
int Test11(ref List<int> lst);
int Test12(TestEnumModel m);
TestEnumModel Test13(TestEnumModel m);
T Test14<T>(T m);
string Test14<T>(T m, int value);
string Test14<T>(T m, string value);
string Test14<T>(T m, TestModel model);
}
IMyTest接口
public interface IMyTest2<T>
{
T Test(T aa);
}
IMyTest2泛型接口
DTO对象:
public class TestModel
{
public int A { get; set; }
} public class TestImpModel : TestModel
{
public string B { get; set; }
} public enum TestEnumModel
{
A = ,
B =
}
DTO对象们
具体实现:
internal class MyTest : IMyTest
{
public int Test1()
{
return ;
} public void Test2()
{ } public int Test3(int value)
{
return value + ;
} public TestModel Test4(ref TestModel T)
{
T.A = T.A + ;
return T;
} public void Test5(TestModel T)
{
T.A = T.A + ;
} public void Test6(out int value)
{
value = ;
} public void Test7(ref int value)
{
value++;
} public int Test8(int value = )
{
return value;
} public int Test9(int value1 = , int value2 = )
{
return value1 + value2;
} public int Test10(params int[] values)
{
return values.Sum();
} public int Test11(ref List<int> lst)
{
lst.Add();
return lst.Sum();
} public int Test12(TestEnumModel m)
{
return (int)m;
} public TestEnumModel Test13(TestEnumModel m)
{
return m;
} public T Test14<T>(T m)
{
return m;
} public string Test14<T>(T m, int value)
{
return m.ToString() + value.ToString();
} public string Test14<T>(T m, string value)
{
return m.ToString() + value;
} public string Test14<T>(T m, TestModel model)
{
model.A += ;
return m.ToString() + model.A.ToString();
}
}
实现了IMyTest的MyTest类
internal class MyTest2<T> : IMyTest2<T>
{
public T Test(T aa)
{
return aa;
}
}
实现了IMyTest2的MyTest2泛型类
测试用例:
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test1());
} [TestMethod]
public void TestMethod2()
{
MyCreator.Create<IMyTest>().Test2();
} [TestMethod]
public void TestMethod3()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test3());
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test3());
} [TestMethod]
public void TestMethod4()
{
var tm = new TestModel() { A = };
var t = MyCreator.Create<IMyTest>().Test4(ref tm);
Assert.AreEqual(, t.A);
Assert.AreEqual(, tm.A);
} [TestMethod]
public void TestMethod5()
{
var t = new TestModel() { A = };
MyCreator.Create<IMyTest>().Test5(t);
Assert.AreEqual(, t.A);
} [TestMethod]
public void TestMethod6()
{
int i = ;
MyCreator.Create<IMyTest>().Test6(out i);
Assert.AreEqual(, i);
} [TestMethod]
public void TestMethod7()
{
int i = ;
MyCreator.Create<IMyTest>().Test7(ref i);
Assert.AreEqual(, i);
} [TestMethod]
public void TestMethod8()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test8());
} [TestMethod]
public void TestMethod9()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test9(value2: ));
} [TestMethod]
public void TestMethod10()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test10(, ));
} [TestMethod]
public void TestMethod11()
{
List<int> lst = new List<int>();
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test11(ref lst));
Assert.AreEqual(, lst.Count);
Assert.AreEqual(, lst[]);
} [TestMethod]
public void TestMethod12()
{
Assert.AreEqual(, MyCreator.Create<IMyTest>().Test12(TestEnumModel.B));
} [TestMethod]
public void TestMethod13()
{
Assert.AreEqual(TestEnumModel.B, MyCreator.Create<IMyTest>().Test13(TestEnumModel.B));
} [TestMethod]
public void TestMethod14()
{
Assert.AreEqual(TestEnumModel.B, MyCreator.Create<IMyTest>().Test14(TestEnumModel.B));
} [TestMethod]
public void TestMethod15()
{
Assert.AreEqual("B123", MyCreator.Create<IMyTest>().Test14(TestEnumModel.B, ));
} [TestMethod]
public void TestMethod16()
{
Assert.AreEqual("Baaaaa", MyCreator.Create<IMyTest>().Test14(TestEnumModel.B, "aaaaa"));
} [TestMethod]
public void TestMethod17()
{
TestImpModel m = new TestImpModel() { A = , B = "" };
Assert.AreEqual("B2", MyCreator.Create<IMyTest>().Test14(TestEnumModel.B, m));
Assert.AreEqual(, m.A);
Assert.AreEqual("", m.B);
} [TestMethod]
public void TestMethod18()
{
TestImpModel m = new TestImpModel() { A = , B = "" };
var n = MyCreator.Create<IMyTest2<TestImpModel>>().Test(m);
Assert.AreEqual(, n.A);
Assert.AreEqual("", n.B);
}
18个简单的测试用例
项目源代码:DynamicWCF.rar
基于Autofac, Castle.DynamicProxy的动态WCF解决方案(原创)的更多相关文章
- ASP.NET Core搭建多层网站架构【9.2-使用Castle.Core实现动态代理拦截器】
2020/01/31, ASP.NET Core 3.1, VS2019, Autofac.Extras.DynamicProxy 4.5.0, Castle.Core.AsyncIntercepto ...
- Castle.DynamicProxy Part 1: ClassProxy
1.Castle中代理对象的分类 总的来说,代理对象大概可以分为2大类: 1.继承类型的代理对象 一类是继承类型的代理类.即:有一个类A,它的代理类是B.B是继承自A的.调用代理类B中的方法时,可以通 ...
- .NET 通过 Autofac 和 DynamicProxy 实现AOP
什么是AOP?引用百度百科:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.实现AOP主要由两 ...
- Autofac高级用法之动态代理
前言 Autofac的DynamicProxy来自老牌的Castle项目.DynamicProxy(以下称为动态代理)起作用主要是为我们的类生成一个代理类,这个代理类可以在我们调用原本类的方法之前,调 ...
- 【转】Autofac高级用法之动态代理
原文:http://www.cnblogs.com/stulzq/p/8547839.html 前言 Autofac的DynamicProxy来自老牌的Castle项目.DynamicProxy(以下 ...
- Castle DynamicProxy基本用法(AOP)
本文介绍AOP编程的基本概念.Castle DynamicProxy(DP)的基本用法,使用第三方扩展实现对异步(async)的支持,结合Autofac演示如何实现AOP编程. AOP 百科中关于AO ...
- 使用Castle DynamicProxy (AOP)
在本文中,我将引导您了解.NET环境中的面向方面编程(AOP)概念,以及如何使用Castle DynamicProxy创建和附加方面.在我们开始之前,让我快速介绍AOP和 IoC.如果您已经熟悉这些 ...
- WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解
上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...
- [AOP系列]Autofac+Castle实现AOP事务
一.前言 最近公司新项目,需要搭架构进行开发,其中需要保证事务的一致性,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实现 ...
随机推荐
- 第三个Sprint冲刺事后诸葛亮报告
用户反馈:还好吧. 用户数量:4 团队改进建议:思维局限太大,技术需要革新. 1.每个成员第一个sprint阶段有何需要改进? 成员 需要改进 邵家文 需要提高自己的工作效率,与创新能力,解决问题的能 ...
- myeclipse10.7破解成功 但 无法打war包 提示:securecrt alert:integrity ch
myeclipse10.7破解成功 但 无法打war包 提示:securecrt alert:integrity check error 找了好久才找到解决办法 http://download. ...
- python 读取并显示图片的两种方法
在 python 中除了用 opencv,也可以用 matplotlib 和 PIL 这两个库操作图片.本人偏爱 matpoltlib,因为它的语法更像 matlab. 一.matplotlib 1. ...
- 简单的射击游戏HTML+JS实现
一直想自己写一个游戏玩,时间和精力都不太允许,最近几天刚好有空闲时间,就琢磨了这个小游戏. 刚开始想着计算图片重叠事件,然后让炮弹和飞机消失,傻乎乎写了一天,越整越乱.今天一大早晕过来了,改用数组以后 ...
- 廖雪峰Python教程疑问
1. 字符串的strip()方法 原文: “把一个序列中的空字符串删掉,可以这么写: def not_empty(s): return s and s.strip() list(filter(not_ ...
- 开启Java博客
已经转Java大半年了,Java知识都来自于工作,没有一个系统的学习,所以这一个多月我都在看Java的一些基本东西,准备系统性的学习下Java知识.这一个多月看的也挺多,从servlet,jsp,st ...
- 如何换ionic里面的图标
(转自http://www.zcool.com.cn/article/ZMTM4NDQw.html) 第一步,你把你的项目的SVG文件跟你自己做的图标的SVG文件都上到icomoon.io/app(上 ...
- 9本java程序员必读的书(附下载地址)
本文列出的9本书在Java程序员界都是被认为很棒的书.当一个程序员开始初学Java时,他的第一个问题应该是如何选择一本书来作为指导学习Java.这个问题也就表明,相对于其他的教程和博客,Java书籍还 ...
- {part1}DFN+LOW(tarjan)割点
什么是jarjan? 1)求割点 定义:在无向连通图中,如果去掉一个点/边,剩下的点之间不连通,那么这个点/边就被称为割点/边(或割顶/桥). 意义:由于割点和割边涉及到图的连通性,所以快速地求出割点 ...
- Android 的 DatePicker、TimePicker或NumberPicker
布局文件加上这个就可以,去除日期选择器.时间选择器或数值选择器的可编辑状态. android:descendantFocusability="blocksDescendants" ...