本方案解决了下面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解决方案(原创)的更多相关文章

  1. 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 ...

  2. Castle.DynamicProxy Part 1: ClassProxy

    1.Castle中代理对象的分类 总的来说,代理对象大概可以分为2大类: 1.继承类型的代理对象 一类是继承类型的代理类.即:有一个类A,它的代理类是B.B是继承自A的.调用代理类B中的方法时,可以通 ...

  3. .NET 通过 Autofac 和 DynamicProxy 实现AOP

    什么是AOP?引用百度百科:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.实现AOP主要由两 ...

  4. Autofac高级用法之动态代理

    前言 Autofac的DynamicProxy来自老牌的Castle项目.DynamicProxy(以下称为动态代理)起作用主要是为我们的类生成一个代理类,这个代理类可以在我们调用原本类的方法之前,调 ...

  5. 【转】Autofac高级用法之动态代理

    原文:http://www.cnblogs.com/stulzq/p/8547839.html 前言 Autofac的DynamicProxy来自老牌的Castle项目.DynamicProxy(以下 ...

  6. Castle DynamicProxy基本用法(AOP)

    本文介绍AOP编程的基本概念.Castle DynamicProxy(DP)的基本用法,使用第三方扩展实现对异步(async)的支持,结合Autofac演示如何实现AOP编程. AOP 百科中关于AO ...

  7. 使用Castle DynamicProxy (AOP)

    在本文中,我将引导您了解.NET环境中的面向方面编程(AOP)概念,以及如何使用Castle DynamicProxy创建和附加方面.在我们开始之前,让我快速介绍AOP和  IoC.如果您已经熟悉这些 ...

  8. WCF分布式开发步步为赢(2)自定义托管宿主WCF解决方案开发配置过程详解

    上一节<WCF分布式框架基础概念>我们介绍了WCF服务的概念和通信框架模型,并给出了基于自定义托管服务的WCF程序的实现代码.考虑到WCF分布式开发项目中关于托管宿主服务配置和客户端添加引 ...

  9. [AOP系列]Autofac+Castle实现AOP事务

    一.前言 最近公司新项目,需要搭架构进行开发,其中需要保证事务的一致性,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实现 ...

随机推荐

  1. test latex1

    equation systems: \begin{equation} 1 + 2 = 3 \ 1 = 3 - 2 \end{equation} align text \begin{align} 1+2 ...

  2. iOS--UIView和UIWindow用法

    基础 UI(user interface)是用户界面:iOS的应用是由各种各样的UI控件组成 UIWindow就是一个窗口,学的第一个基础类,就是一个容器,可以在容器上放不同的内容,每个app都需要借 ...

  3. GWAS Simulation

    comvert hmp to ped1, ped2, map fileSB1.ped, SB2.ped, SB.map 1, choose 20 markers for 30 times(WD: /s ...

  4. OAuth2.0授权

    一.什么是OAuth2.0官方网站:http://oauth.net/ http://oauth.net/2/ 权威定义:OAuth is An open protocol to allow secu ...

  5. null和undefined区别(转)

    目前,null和undefined基本是同义的,只有一些细微的差别. null表示"没有对象",即该处不应该有值.典型用法是: (1) 作为函数的参数,表示该函数的参数不是对象. ...

  6. json loads No JSON object could be decoded 问题解决

    今天自己用json的 dumps生成的 json 文本: f2=open(filename,'w')f2.write(json.dumps(c) f=open(filename,'r')r= f.re ...

  7. [NOIP2011] 聪明的质检员(二分答案)

    题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...

  8. 关于从jsp 中 引用 js 中的里层function

    在需要引用的方法里: 需要引用的方法 function (){ new js中的父方法().子方法(参数) }

  9. python 3 学习笔记(二)

    1.python中的数据类型 python使用对象模型来存储数据,每一个数据类型都有一个内置的类,每新建一个数据,实际就是在初始化生成一个对象,即所有数据都是对象对象三个特性 身份:内存地址,可以用i ...

  10. 如何在JAVA中实现一个固定最大size的hashMap

    如何在JAVA中实现一个固定最大size的hashMap 利用LinkedHashMap的removeEldestEntry方法,重载此方法使得这个map可以增长到最大size,之后每插入一条新的记录 ...