标签:fsharp f# enterprise library interceptor unity
policy interceptionopen System
open System.Collections
open Microsoft.Practices.Unity
open Microsoft.Practices.Unity.InterceptionExtension
type ITenantStore =
abstract member Msg : unit->unit
type TenantStore() as x=
//do printfn "new TenantStore %A" (x.GetHashCode())
abstract Msg : unit -> unit
default x.Msg() =
printfn "Hello, it's TenantStore"
abstract Dispose : unit -> unit
default x.Dispose() =
printfn "TenantStore hase been cleaned"
interface ITenantStore with
member x.Msg() =
x.Dispose() //测试Virtual Method中拦截内部方法的结果
x.Msg()
interface IDisposable with
member x.Dispose() =
x.Dispose()声明实现ICallHandler接口的类。此处有一个地方需要注意。还是Fsharp语言的特性,无法隐式对接口进行转换。Fsharp的接口都是显示声明实现。如果不在类中暴露Order属性,在注册CallHandler的时候会提示缺少Order属性。好在ICallHandler接口比IInterceptionBehavior功能少,附加的点也就这一个。type LoggingCallHandler() =
let WriteLog message =
printfn "From the logging interceptor: %A" message
member val Order=0 with get,set
interface ICallHandler with
member x.Invoke((input:IMethodInvocation), (getNext:GetNextHandlerDelegate)) =
String.Format("Invoke method {0}:{2} at {1}", input.MethodBase, DateTime.Now.ToLongTimeString(), input.MethodBase.DeclaringType) |> WriteLog
let result = getNext.Invoke().Invoke(input, getNext)
match result.Exception with
| null ->
String.Format("Method {0}:{3} returned {1} at {2}", input.MethodBase, result.ReturnValue, DateTime.Now.ToLongTimeString(), input.MethodBase.DeclaringType) |> WriteLog
| _ ->
String.Format("Method {0} threw exception {1} at {2}", input.MethodBase, result.Exception.Message, DateTime.Now.ToLongTimeString()) |> WriteLog
result
member x.Order with get()=x.Order and
set(v) = x.Order <- v下面是具体的注册调用using(new UnityContainer())(fun ctner->
ctner.AddNewExtension<Interception>() |> ignore
ctner.RegisterType<ITenantStore, TenantStore>(new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<VirtualMethodInterceptor>()) |> ignore
let first = new InjectionProperty("Order", 1)
ctner.Configure<Interception>().AddPolicy("logging")
.AddMatchingRule<MemberNameMatchingRule>(new InjectionConstructor([|"Msg"|], true))
.AddCallHandler<LoggingCallHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor(),first) |> ignore
showregistrations ctner
let t = ctner.Resolve<ITenantStore>()
t.Msg()
)type LoggingCallHandler() =
let WriteLog message =
printfn "From the logging interceptor: %A" message
member val Order=0 with get,set
interface ICallHandler with
member x.Invoke((input:IMethodInvocation), (getNext:GetNextHandlerDelegate)) =
String.Format("Invoke method {0}:{2} at {1}", input.MethodBase, DateTime.Now.ToLongTimeString(), input.MethodBase.DeclaringType) |> WriteLog
let result = input.CreateMethodReturn(0) //break the pipe line
//let result = getNext.Invoke().Invoke(input, getNext)
match result.Exception with
| null ->
String.Format("Method {0}:{3} returned {1} at {2}", input.MethodBase, result.ReturnValue, DateTime.Now.ToLongTimeString(), input.MethodBase.DeclaringType) |> WriteLog
| _ ->
String.Format("Method {0} threw exception {1} at {2}", input.MethodBase, result.Exception.Message, DateTime.Now.ToLongTimeString()) |> WriteLog
result
member x.Order with get()=x.Order and
set(v) = x.Order <- v
type LoggingCallHandler2() =
let WriteLog message =
printfn "From the logging interceptor: %A" message
member val Order=0 with get,set
interface ICallHandler with
member x.Invoke((input:IMethodInvocation), (getNext:GetNextHandlerDelegate)) =
String.Format("Invoke method2 {0}:{2} at {1}", input.MethodBase, DateTime.Now.ToLongTimeString(), input.MethodBase.DeclaringType) |> WriteLog
//let result = getNext.Invoke().Invoke(input, getNext)
let result = input.CreateMethodReturn(0) //break the pipe line
match result.Exception with
| null ->
String.Format("Method2 {0}:{3} returned {1} at {2}", input.MethodBase, result.ReturnValue, DateTime.Now.ToLongTimeString(), input.MethodBase.DeclaringType) |> WriteLog
| _ ->
String.Format("Method2 {0} threw exception {1} at {2}", input.MethodBase, result.Exception.Message, DateTime.Now.ToLongTimeString()) |> WriteLog
result
member x.Order with get()=x.Order and
set(v) = x.Order <- vusing(new UnityContainer())(fun ctner->
ctner.AddNewExtension<Interception>() |> ignore
ctner.RegisterType<ITenantStore, TenantStore>(new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<VirtualMethodInterceptor>()) |> ignore
let first = new InjectionProperty("Order", 1)
let second = new InjectionProperty("Order", 2)
ctner.Configure<Interception>().AddPolicy("logging")
.AddMatchingRule<MemberNameMatchingRule>(new InjectionConstructor([|"Msg"|], true))
.AddCallHandler<LoggingCallHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor(),second) |> ignore
ctner.Configure<Interception>().AddPolicy("logging2")
.AddMatchingRule<MemberNameMatchingRule>(new InjectionConstructor([|"Msg"|], true))
.AddCallHandler<LoggingCallHandler2>(new ContainerControlledLifetimeManager(), new InjectionConstructor(),first) |> ignore
showregistrations ctner
let t = ctner.Resolve<ITenantStore>()
t.Msg()
)通过fsharp 使用Enterprise Library Unity 4 - Policy Interjection
标签:fsharp f# enterprise library interceptor unity
原文地址:http://blog.csdn.net/samwell/article/details/40739949