我有一个托管在Windows服务中的wcf服务库。我需要拦截来电 服务方式。对于这种情况,建议将WCF注册到Unity容器中,如此链接中所示
http://weblogs.asp.net/fabio/archive/2009/03/24/inversion-of-control-with-wcf-and-unity.aspx
我正在尝试通过Codeplex中的Unity.WCF程序集实现类似的方法。我无法理解将容器配置或引导程序放在wcf服务库(或Windows服务)中的位置。没有提供固体样本(vs解决方案)。
我的Windows服务主机
private UnityServiceHost _serviceHost = null;
private readonly UnityContainer _container;
public Service() {
InitializeComponent();
_container = new UnityContainer();
_container.AddNewExtension<Interception>();
_container.RegisterType<ISecurityRepository, SecurityRepository>();
_container.Configure<Interception>().SetDefaultInterceptorFor<ISecurityRepository>(new TransparentProxyInterceptor());
}
protected override void OnStart(string[] args) {
//SecurityService
if (_serviceHost != null) {
_serviceHost.Close();
} else {
_serviceHost = new UnityServiceHost(_container, typeof(SecurityRepository));
_serviceHost.Open();
}
}
protected override void OnStop() {
//SecurityService
if (_serviceHost != null) {
_serviceHost.Close();
_serviceHost = null;
}
}
我的服务合同
[ServiceContract(SessionMode = SessionMode.Required)]
public interface ISecurityRepository
{
[OperationContract(IsInitiating = true)]
IList<vNavigationTree> GetNavigationTree(string ticket);
[OperationContract(IsInitiating = true)]
string GetSessionGuid(string userName, string IP, string machineName);
}
在这种情况下,似乎拦截器不起作用。简而言之,我需要的是一个示例项目,其中WCF服务注册到DI容器并且拦截了服务方法。
答案 0 :(得分:2)
我会尝试更明确地解释我尝试做的事情以及我是如何设法做到的。我有一个WPF应用程序通过WCF与数据库通信,这意味着我的应用程序大致分为两个:客户端和服务器端(WCF)。我已经通过PRISM提供的UnityBootStrapper将客户端包装到Unity容器中。我还需要将服务器端包装到另一个Unity容器中,以使Unity解析服务器端依赖关系。
我的问题由Unity.WCF(作为Nuget包提供)解决,它提供了可用于代替ServiceHost的UnityServiceHost类。我想这个包是按照这篇文章解释的方式创建的:
http://weblogs.asp.net/fabio/archive/2009/03/24/inversion-of-control-with-wcf-and-unity.aspx
答案 1 :(得分:1)
您需要做的是利用统一拦截管道。
Unity提供了内置的策略注入行为,以便于执行aop。策略注入行为通过在每个方法的基础上使用调用处理程序和匹配规则来附加或注入特定方法的某些功能。
一个。从ICallhandler的自定义界面开始。
>> public interface ILogAttributeHandler : ICallHandler
>> {
>> }
>>
湾为您的处理程序添加实现。这是您在拦截方法时要应用的建议。
>> public class ActivityAttributeHandler : ILogAttributeHandler
>> {
>> public ActivityAttributeHandler(string activityType)
>> {
>> ActivityType = activityType;
>> }
>> private string ActivityType { get; set; }
>> public int Order { get; set; }
>> public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
>> {
>> //// Invoke the handler
>> IMethodReturn output = getNext()(input, getNext);
>> //// Perform post-processing task
>> var agent = output.ReturnValue as Agent;
>> if (agent != null)
>> {
>> //// do work here
>> }
>> return getNext()(input, getNext);
>> }
}
℃。创建自定义属性,这将用作程序中的切入点。
>> [AttributeUsage(AttributeTargets.Method)]
>> public class ActivityAttribute : HandlerAttribute
>> {
>> private readonly string _activityName;
>> public ActivityAttribute(string activityName)
>> {
>> _activityName = activityName;
>> }
>> }
>> public override ICallHandler CreateHandler(IUnityContainer container)
>> {
>> return null;
>>}
d。现在您剩下的就是在Unity配置中配置拦截,并将该属性添加到您想要拦截的服务接口操作中。
> container
> .RegisterType<ILogAttributeHandler, LogAttributeHandler>()
> .AddNewExtension<Interception>()
> .Configure<Interception>()
> .SetInterceptorFor<ISecurityRepository>("SecurityRepository", new
> InterfaceInterceptor());
即将属性应用于接口操作
>>public interface ISecurityRepository
>> {
>> [OperationContract(IsInitiating = true)]
>> [Activity("Logon")]
>> IList<vNavigationTree> GetNavigationTree(string ticket)
>>}