WCF 依赖注入-- Attribute
最近,工作之余学习WCF(Windows Communication Fundation)时,感觉自己还有好多的东西需要学习呀⊙﹏⊙b汗,于是想记录下自己学习WCF的心得,以鼓励自己再接再厉,同时希望可以为其他想学习WCF的园友们抛砖引玉,虽然有很多大侠们已经写了很多类似的文章了。
结合现实开发项目的情形,想在WCF服务中实现构造函数的依赖注入,就像在MVC中有一个名为DefaultControllerFactory的入口一样,那么在WCF中是否也有类似的类呢?下面是在MSDN中提到了三种方法:
- 以编程方式,先将自定义服务行为添加到 Behaviors 属性,然后对 System.ServiceModel.ServiceHost 对象调用 ICommunicationObject.Open 方法。
- 创建一个可实现 IServiceBehavior 的自定义属性,并利用它来标记要修改的服务类。 构造 ServiceHost 对象时, 会使用反射来发现服务类型的属性。 如果有属性实现 IServiceBehavior,则它们将会被添加到 ServiceDescription 上的行为集合中。
- 扩展 System.ServiceModel.Configuration.BehaviorExtensionElement 类,以支持应用程序配置文件或计算机配置文件中的行为规范。
本文主要是使用第二种方法(Attribute)实现依赖注入。
在上列子之前,需要我们了解两个接口:IInstanceProvider 和 IServiceBehavior。
IInstanceProvider接口 声明一些方法,以便为服务提供服务对象,或回收该服务的服务对象。(MSDN)
IServiceBehavior接口 提供一种在整个服务内修改或插入自定义扩展的机制,包括 ServiceHostBase。(MSDN)
本例中使用的是NInject注入工具,需要了解NInject的园友可以登录官网:http://www.ninject.org/。闲话少说了,进入正题……
- 新建一个类NInjectContainer, 主要是作为IoC容器,以便于后面依赖的注入。
public class NInjectContainer : NinjectModule
{
public override void Load()
{
Bind<IUserRepository>().To<UserRepository>();
Bind<UserService>().ToSelf().InSingletonScope();
} private IKernel _kernel; public IKernel StandardKernel
{
get
{
if(_kernel == null)
{
_kernel = new StandardKernel(this);
}
return _kernel;
}
}
}NinjectModule是Ninject提供的,想了解的可以去官网看看。
- 新建一个类NInjectInstanceProvider,该类继承 IInstanceProvider,该类主要是为服务提供服务对象,或回收该服务的服务对象
public class NInjectInstanceProvider : IInstanceProvider
{
public NInjectContainer Container { get; private set; }
public Type ServiceType { get; set; } public NInjectInstanceProvider(Type type)
{
ServiceType = type;
Container = new NInjectContainer();
} public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
} public object GetInstance(InstanceContext instanceContext, Message message)
{
return Container.StandardKernel.Get(ServiceType);
} public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
Debug.WriteLine("ReleaseInstance");
}
} - 新建一个类NInjectServiceBehaviorAttribute,该类继承Attribute类,同时实现IServiceBehavior接口,该类主要提供一种在整个服务内修改或插入自定义扩展的机制
public class NInjectServiceBehaviorAttribute : Attribute, IServiceBehavior
{
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{ } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{ } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (var item in serviceHostBase.ChannelDispatchers)
{
var dispatcher = item as ChannelDispatcher;
if (dispatcher != null)
{
dispatcher.Endpoints.ToList().ForEach(ep =>
{
ep.DispatchRuntime.InstanceProvider =
new NInjectInstanceProvider(
serviceDescription.ServiceType);
});
}
}
}
} - 新建一个服务IUserService及UserService,同时将NInjectServiceBehaviorAttribute应用在需要注入的服务上面
[ServiceContract(Namespace = "http://www.iyasoft.cn.Samples")]
public interface IUserService
{
[OperationContract]
string Add(User user); [OperationContract]
string Update(User user); [OperationContract]
string Delete(string name); [OperationContract]
string GetUsers(); } [NInjectServiceBehavior]
public class UserService : IUserService
{
private readonly IUserRepository _repository; public UserService(IUserRepository repository)
{
_repository = repository;
} public string Add(User user)
{
return _repository.Add(user);
} public string Update(User user)
{
return _repository.Update(user);
} public string Delete(string name)
{
return _repository.Delete(name);
} public string GetUsers()
{
return _repository.GetUsers();
}
}
主函数的调用如下:
class Program
{
static void Main(string[] args)
{
try
{
ServiceHostBase host = new ServiceHost(typeof(UserService));
host.Opened += (sender, e) => Console.WriteLine("server is opened");
host.Open(); var channelFactory = new ChannelFactory<IUserService>("client");
IUserService userService1 = channelFactory.CreateChannel();
Console.WriteLine(userService1.Add(new User()));
Console.WriteLine(userService1.Delete("user"));
Console.WriteLine(userService1.Update(new User()));
Console.WriteLine(userService1.GetUsers());
channelFactory.Close(); Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine(); Console.WriteLine("\n+++ press any key to close a ServiceHost +++\n");
Console.ReadLine(); host.Close(); }
catch { }
}
这样就完成了WCF中服务的依赖注入......,下面我们看看运行结果:

我也是新学习WCF的菜鸟,不对的地方请各位大侠指出,谢谢!
附上源码:WcfServiceDependencyInject.rar
WCF 依赖注入-- Attribute的更多相关文章
- 大比速:remoting、WCF(http)、WCF(tcp)、WCF(RESTful)、asp.net core(RESTful) .net core 控制台程序使用依赖注入(Autofac)
大比速:remoting.WCF(http).WCF(tcp).WCF(RESTful).asp.net core(RESTful) 近来在考虑一个服务选型,dotnet提供了众多的远程服务形式.在只 ...
- Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor
Webservice WCF WebApi 注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...
- Unity文档阅读 第三章 依赖注入与Unity
Introduction 简介In previous chapters, you saw some of the reasons to use dependency injection and lea ...
- 在WPF中使用依赖注入的方式创建视图
在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...
- ASP.NET Core中的依赖注入(2):依赖注入(DI)
IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...
- Java之控制反转和依赖注入
1.简介 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性,下面通过一个例子来引入这一概念. 2.案例 1)一般情况下的类耦合 Main.java public clas ...
- 采用dom4j和反射模拟Spring框架的依赖注入功能
Spring的依赖注入是指将对象的创建权交给Spring框架,将对象所依赖的属性注入进来的行为.在学习了dom4j后,其实也可以利用dom4j和反射做一个小Demo模拟Spring框架的这种功能.下面 ...
- Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->使用spring framework的IoC容器功能----->方法一:使用XML文件定义beans之间的依赖注入关系
XML-based configuration metadata(使用XML文件定义beans之间的依赖注入关系) 第一部分 编程思路概述 step1,在XML文件中定义各个bean之间的依赖关系. ...
- Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->Spring Framework的依赖注入和控制反转
Dependency Injection and Inversion of Control 1.概述: 1.1相关概念 bean:由IoC容器所管理的对象,也即各个类实例化所得对象都叫做bean 控制 ...
随机推荐
- Linux环境下的Nginx编译与安装
1.新建文件夹: mkdir -p /zuker cd /zuker 2.编译: yum -y install gcc-c++ make wget autoconf libjpeg libjpeg-d ...
- Subsonic的使用之基本语法、操作(2)
查询 SubSonic2.1版本 – 例出3种查询. Product product = new Select().From<Product>() .Where(Product.Produ ...
- CentOS7中DHCP配置
因为需要网络引导系统的安装,所以需要安装和配置DHCP服务器.DHCP(Dynamic Host Configuration Protocol) 动态主机配置协议,它提供了一种动态指定IP地址和配置参 ...
- iOS @@创建NSURL的字面量
@@ 是创建 NSURL 的字面量的绝佳方法(例如:@@"http://example.com")
- 1.1 Quartz 2D 绘图
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” Quartz2D 绘图主要步骤: 1. 获取[图形上下文]对象 —— (拿到草稿纸 ...
- hdu4135 容斥定理
Co-prime Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- std::string的split函数
刚刚要找个按空格分离std::string的函数, 结果发现了stackoverflow上的这个问题. 也没仔细看, 直接拿来一试, 靠, 不对啊, 怎么分离后多出个空字符串, 也就是 "a ...
- ZeroMQ接口函数之 :zmq_ctx_get - 得到环境上下文的属性
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_ctx_get zmq_ctx_get(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_c ...
- android4.4源码下载简介
1. $sudo apt-get install git-core curl2. mkdir ~/bin PATH=~/bin:$PATH3. curl http://commondatastorag ...
- Javascript的shift()和push(),unshift()和pop()方法简介
栈方法: Javascript为数组专门提供了push()和pop()方法,以便实现类似栈的行为.来看下面的例子: var colors=new Array(); //创建一个数组 var ...