文章目录
1、通过编码方式使用Unity容器的步骤
1.准备基础业务类
CourseOrder课程订单实体类:
public class CourseOrder
{
public int OrderId { get; set; }
public int CourseId { get; set; }
public string CourseName { get; set; }
public int CoursePrice { get; set; }
public int SchoolId { get; set; }
public int StudentId { get; set; }
}
IOrderService课程订单接口:
public interface IOrderService
{
//提交订单
int SubmitOrder(CourseOrder order);
//查询订单
List<CourseOrder> QueryOrders();
}
OrderService课程订单实现类:
/// <summary>
/// 接口的实现(功能性业务)
/// </summary>
class OrderService : IOrderService
{
public List<CourseOrder> QueryOrders()
{
//实际项目中,在这里写具体查询任务...
return new List<CourseOrder>()
{
new CourseOrder{
CourseId = 1002,
CourseName = ".NET高级VIP课程2",
CoursePrice = 5501,
SchoolId = 502103,
StudentId = 2200229, },
};
}
public int SubmitOrder(CourseOrder order)
{
//实际项目中,在这里写具体查询任务...
Console.WriteLine("------------【提交订单成功】------------");
//如果你不用AOP思想的话,你可能想到,这个地方写调用第三方支付接口完成支付等任务(如提醒业务)...
return 1000;
}
}
2.添加Unity容器的引用
使用NuGet管理器添加Unity容器的引用,如下:
3.给基础业务添加具体的注入类
编写三个具体的注入类,都继承ICallHandler如下:
//需要引用命名空间 using Unity.Interception.PolicyInjection.Pipeline;
//需要引入命名空间 using Unity.Interception.PolicyInjection.Policies;
#region 扩展我们需要的行为类
//数据校验类
class DataValidateHandler : ICallHandler
{
public int Order { get; set; }//这个是标识注入顺序的属性
/// <summary>
/// 注入的行为
/// </summary>
/// <param name="input">输入参数</param>
/// <param name="getNext">调用下一个行为的委托</param>
/// <returns></returns>
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
CourseOrder order = input.Inputs[0] as CourseOrder;
//实现验证的过程
if (order.StudentId.ToString().Length < 6)
{
return input.CreateExceptionMethodReturn(new Exception("学号长度不能小于6位"));
}
if (order.CoursePrice < 100)
{
return input.CreateExceptionMethodReturn(new Exception("价格不能小于100元"));
}
Console.WriteLine("订单数据校验成功");
return getNext()(input, getNext);//跳转到下一个 注入的行为,并返回结果(F12可以发现,这是一个用委托定义的委托,所以这里的写法是委托的嵌套)
}
}
//缓存类
class CacheHandler : ICallHandler
{
public int Order { get; set; }//这个是标识注入顺序的属性
/// <summary>
/// 注入的行为
/// </summary>
/// <param name="input">输入参数</param>
/// <param name="getNext">调用下一个行为的委托</param>
/// <returns></returns>
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
CourseOrder order = input.Inputs[0] as CourseOrder;
//这里编写具体的过程
Console.WriteLine("缓存写入成功");
return getNext()(input, getNext);//跳转到下一个 注入的行为,并返回结果
}
}
//日志添加类
class WriteLogHandler : ICallHandler
{
public int Order { get; set; }//这个是标识注入顺序的属性
/// <summary>
/// 注入的行为
/// </summary>
/// <param name="input">输入参数</param>
/// <param name="getNext">调用下一个行为的委托</param>
/// <returns></returns>
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
CourseOrder order = input.Inputs[0] as CourseOrder;
//这里编写具体的过程
Console.WriteLine("日志写入成功");
return getNext()(input, getNext);//跳转到下一个 注入的行为,并返回结果
}
}
#endregion
4.将当前的扩展类包装为特性类
封装上一步的三个注入类为特性类,供接口使用,如下:
//需要引入命名空间 using Unity.Interception.PolicyInjection.Pipeline;
//需要引入命名空间 using Unity.Interception.PolicyInjection.Policies;
#region 封装特性类
public class DataValidateHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new DataValidateHandler { Order = this.Order };
}
}
public class CacheHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new CacheHandler { Order = this.Order };
}
}
public class WriteLogHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new WriteLogHandler { Order = this.Order };
}
}
#endregion
5.给接口增加特性类
给需要切入的接口,添加特性类,如下:
/// <summary>
/// 课程订单接口
/// </summary>
///
[WriteLogHandler(Order = 10)]
[DataValidateHandler(Order = 5)]
[CacheHandler(Order = 8)]
public interface IOrderService
{
//提交订单
int SubmitOrder(CourseOrder order);
//查询订单
List<CourseOrder> QueryOrders();
}
6.使用Unity容器
使用Unity容器的格式,如下:
//需要引入命名空间
//using Unity;
//using Unity.Interception.ContainerIntegration;
//using Unity.Interception.Interceptors.InstanceInterceptors.InterfaceInterception;
class Program
{
static void Main(string[] args)
{
//【1】获取容器
IUnityContainer container = new UnityContainer();
//【2】注册服务
container.RegisterType<IOrderService, OrderService>();
//【3】注入业务
container.AddNewExtension<Interception>().Configure<Interception>().SetInterceptorFor<IOrderService>(new InterfaceInterceptor());
//【4】创建对象
IOrderService orderService = container.Resolve<IOrderService>();
//【5】业务调用
CourseOrder order = new CourseOrder
{
CourseId = 1001,
CourseName = ".NET高级VIP课程",
CoursePrice = 3500,
SchoolId = 502102,
StudentId = 293400,
};
orderService.SubmitOrder(order);
Console.ReadLine();
}
}
2、通过配置文件使用Unity容器
1.添加两个独立的引用(dll文件)
两个独立的引用分别是:
Microsoft.Practices.Unity.Configuration.dll
Microsoft.Practices.Unity.dll
还需要添加程序集中的:System.Configuration
2.添加业务接口和实现
同1.1(编码方式实现Unity容器的第一节)
OrderService课程订单实现类做了一点改动,如下:
/// <summary>
/// 接口的实现(功能性业务)
/// </summary>
class OrderService1 : IOrderService
{
public List<CourseOrder> QueryOrders()
{
//实际项目中,在这里写具体查询任务...
return new List<CourseOrder>()
{
new CourseOrder{
CourseId = 2002,
CourseName = ".NET高级VIP课程1",
CoursePrice = 5501,
SchoolId = 502103,
StudentId = 2200229, },
};
}
public int SubmitOrder(CourseOrder order)
{
//实际项目中,在这里写具体查询任务...
Console.WriteLine("------------【OrderService1提交订单成功】------------");
//如果你不用AOP思想的话,你可能想到,这个地方写调用第三方支付接口完成支付等任务(假如提醒业务)...
return 1000;
}
}
class OrderService2 : IOrderService
{
public List<CourseOrder> QueryOrders()
{
//实际项目中,在这里写具体查询任务...
return new List<CourseOrder>()
{
new CourseOrder{
CourseId = 2002,
CourseName = ".NET高级VIP课程2",
CoursePrice = 5501,
SchoolId = 502103,
StudentId = 2200229, },
};
}
public int SubmitOrder(CourseOrder order)
{
//实际项目中,在这里写具体查询任务...
Console.WriteLine("------------【OrderService2提交订单成功】------------");
//如果你不用AOP思想的话,你可能想到,这个地方写调用第三方支付接口完成支付等任务(假如提醒业务)...
return 1000;
}
}
3.修改配置文件进行配置
修改App.config,增加我们需要配置的节点,如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<!--注册业务类型-->
<aliases>
<add alias="IOrderService" type="xiketang.com.UnityTeach2.IOrderService,xiketang.com.UnityTeach2" />
<add alias="OrderService1" type="xiketang.com.UnityTeach2.OrderService1,xiketang.com.UnityTeach2" />
<add alias="OrderService2" type="xiketang.com.UnityTeach2.OrderService2,xiketang.com.UnityTeach2" />
</aliases>
<containers>
<!--MyContainer是自定义的容器名称-->
<!--type是接口名称,mapTo是注入的对象名称,name是我们要使用的名称-->
<container name="MyContainer">
<register type="IOrderService" mapTo="OrderService1" name="MyOrderService1" />
<register type="IOrderService" mapTo="OrderService2" name="MyOrderService2" />
</container>
</containers>
</unity>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
4.使用Unity容器加载配置文件
//需要引用命名空间
//using System.Configuration;
//using Microsoft.Practices.Unity.Configuration;
//using Microsoft.Practices.Unity;
class Program
{
static void Main(string[] args)
{
//【1】创建容器对象,并加载配置文件
IUnityContainer container = new UnityContainer();
container.LoadConfiguration("MyContainer");
//【2】获得指定配置节点,并获得节点内部详情
UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
//【3】根据指定的name字符串返回对象
IOrderService orderService = container.Resolve<IOrderService>("MyOrderService1");
//【4】核心业务调用
orderService.SubmitOrder(new CourseOrder());
Console.ReadLine();
}
}