(抽象)工厂的另一种实现方式
工厂模式是在设计模式中比较容易理解和掌握的一种模式,其使用非常的普遍。在项目实践中个人对常用的工厂模式做了一个调整,整个实现有点像工厂模式和抽象工厂模式的混合体,这样做的好处在于结合工厂模式的易用和抽象工厂的灵活。具体的实现可能如下:
在这个Case中有2个类,2个接口。其中IServiceFactory定义了工厂的职责GetService<T>,ServiceFactory实现IServiceFactory接口(注意接口是显示实现,这个很重要,因为类的静态方法和实例方法签名不能相同)。
ServiceFactory.cs

1 public class ServiceFactory:IServiceFactory
2 {
3 private static IServiceFactory _inc;
4
5 private ServiceFactory()
6 {
7
8 }
9 static ServiceFactory()
10 {
11
12 _inc = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<IServiceFactory>();
13 if (_inc == null)
14
15 _inc = new ServiceFactory();
16 }
17
18 public static T GetService<T>()
19 {
20 return _inc.GetService<T>();
21 }
22
23 T IServiceFactory.GetService<T>()
24 {
25 return default(T);
26 }
27 }
2 {
3 private static IServiceFactory _inc;
4
5 private ServiceFactory()
6 {
7
8 }
9 static ServiceFactory()
10 {
11
12 _inc = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<IServiceFactory>();
13 if (_inc == null)
14
15 _inc = new ServiceFactory();
16 }
17
18 public static T GetService<T>()
19 {
20 return _inc.GetService<T>();
21 }
22
23 T IServiceFactory.GetService<T>()
24 {
25 return default(T);
26 }
27 }
作为ServiceFactory的调用者在使用上和普通的工厂没有任何区别,利用IOC容器可以非常方便的用Mok对象来降低对具体业务的依赖性,极大的了方便单元测试。同时我们也可以通过条件编译在发布的时候去掉对IoC容器的依赖。
Test:

1 IUnityContainer container;
2 [Test]
3 public void CalculateTest()
4 {
5 Setup();
6
7 var factoryMock = new Mock<IServiceFactory>();//Mock Factory
8 var calcMock = new Mock<ICalculateService>();//Mock Service
9 calcMock.Setup(c => c.Sum(It.IsAny<int>(), It.IsAny<int>())).Returns<int, int>((x, y) => x + y); //Mock Calculate Sum Method
10 factoryMock.Setup(c => c.GetService<ICalculateService>()).Returns(calcMock.Object); //Mock GetService<T> Method
11
12 container.RegisterInstance<IServiceFactory>(factoryMock.Object);//向容器中注入Mock的Factory
13
14 var calc = ServiceFactory.GetService<ICalculateService>();
15
16 Assert.IsNotNull(calc);
17 int a = 1;
18 int b = 2;
19 int experct = a + b;
20 int actual = calc.Sum(a, b);
21 Assert.IsTrue(experct == actual);
22 }
23
24 public void Setup()
25 {
26 container = new UnityContainer();
27 Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current = new UnityServiceLocator(container);
28 }
2 [Test]
3 public void CalculateTest()
4 {
5 Setup();
6
7 var factoryMock = new Mock<IServiceFactory>();//Mock Factory
8 var calcMock = new Mock<ICalculateService>();//Mock Service
9 calcMock.Setup(c => c.Sum(It.IsAny<int>(), It.IsAny<int>())).Returns<int, int>((x, y) => x + y); //Mock Calculate Sum Method
10 factoryMock.Setup(c => c.GetService<ICalculateService>()).Returns(calcMock.Object); //Mock GetService<T> Method
11
12 container.RegisterInstance<IServiceFactory>(factoryMock.Object);//向容器中注入Mock的Factory
13
14 var calc = ServiceFactory.GetService<ICalculateService>();
15
16 Assert.IsNotNull(calc);
17 int a = 1;
18 int b = 2;
19 int experct = a + b;
20 int actual = calc.Sum(a, b);
21 Assert.IsTrue(experct == actual);
22 }
23
24 public void Setup()
25 {
26 container = new UnityContainer();
27 Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current = new UnityServiceLocator(container);
28 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?