最近,工作之余学习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的更多相关文章

  1. 大比速: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提供了众多的远程服务形式.在只 ...

  2. 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平台下, ...

  3. Unity文档阅读 第三章 依赖注入与Unity

    Introduction 简介In previous chapters, you saw some of the reasons to use dependency injection and lea ...

  4. 在WPF中使用依赖注入的方式创建视图

    在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...

  5. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  6. Java之控制反转和依赖注入

    1.简介 依赖注入和控制反转,目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性,下面通过一个例子来引入这一概念. 2.案例 1)一般情况下的类耦合 Main.java public clas ...

  7. 采用dom4j和反射模拟Spring框架的依赖注入功能

    Spring的依赖注入是指将对象的创建权交给Spring框架,将对象所依赖的属性注入进来的行为.在学习了dom4j后,其实也可以利用dom4j和反射做一个小Demo模拟Spring框架的这种功能.下面 ...

  8. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->使用spring framework的IoC容器功能----->方法一:使用XML文件定义beans之间的依赖注入关系

    XML-based configuration metadata(使用XML文件定义beans之间的依赖注入关系) 第一部分 编程思路概述 step1,在XML文件中定义各个bean之间的依赖关系. ...

  9. Spring Framework------>version4.3.5.RELAESE----->Reference Documentation学习心得----->Spring Framework的依赖注入和控制反转

    Dependency Injection and Inversion of Control 1.概述: 1.1相关概念 bean:由IoC容器所管理的对象,也即各个类实例化所得对象都叫做bean 控制 ...

随机推荐

  1. [工作中的设计模式]责任链模式chain

    一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

  2. 分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...

  3. Page-encoding specified in XML prolog (UTF-8) is different from that specified in page directive (utf-8)

    org.apache.jasper.JasperException:xxx.jsp(1,1) Page-encoding specified in XML prolog (UTF-8) is diff ...

  4. .net core 基本概念

    asp.net core 是基于 .net core的,所以能够跨平台. 目前存在.NET Framework (CLR), .NET Core (CoreCLR) or Mono,可根据项目的具体情 ...

  5. Android sdk资源包res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)

    (1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854) (2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x ...

  6. [Android]关于filed 遍历资源文件的排序问题

    Field[] svgfields = R.drawable.class.getFields(); listid = new ArrayList<Integer>(); for (Fiel ...

  7. 第一章-第一题(小学生四则运算)--By郭青云

    1.项目需求 a) 除了整数以外,还要支持真分数的四则运算. (例如:  1/6 + 1/8 = 7/24) b) 让程序能接受用户输入答案,并判定对错. 最后给出总共 对/错 的数量. c) 逐步扩 ...

  8. PHP的流程控制结构

    1.break 使用break语句可以将深埋在嵌套循环中的语句退出到指定层数或直接退出到最外层,break是接受一个可选的数字参数来决定跳出几重语句.break可以跳出几重语句.break可以跳出几重 ...

  9. 【iCore3 双核心板_FPGA】实验二十八:基于SDRAM 的VGA 驱动器的设计

    本实验设计的VGA显示驱动完全基于FPGA实现,用SDRAM做缓存设备,通过ARM控制VGA显示的内容.ARM 通过FSMC总线向FPGA发送数据,由于总线的速度和VGA的显示速度与SDRAM的读写速 ...

  10. soui中,列表控件动态高度的使用注意

    1.listview的模板template中,需要增加defHeight属性,即默认高度,同时,不能出现itemHeight属性,否则动态高度会失效 2.数据适配器中,重写getViewDesired ...