最近,工作之余学习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. Socket 类通信例子-第24章

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. 【Oracle】oracle中快速判断某一日期是闰年或平年

    )),' then '平年' else '闰年' end as isLeapYear from dual 第一步:取日期的年初日期:第二步:年初日期增加一个月即概念2月:第三步:取概念2月的最后一天的 ...

  3. jQuery学习之:Validation表单验证插件

    http://polaris.blog.51cto.com/1146394/258781/ 最近由于公司决定使用AJAX + Struts2来重构项目,让我仔细研究一下这两个,然后集中给同事讲讲,让每 ...

  4. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  5. python中文注释报错问题

    错误信息: SyntaxError: Non-ASCII character '\xe4' in file... 解决办法: 在文件第一行或第二行添加:# -*- coding: utf-8 -*- ...

  6. XMLHttpRequest对象用法

    xmlhttprequest is what? 用户后台与服务器交换数据. 可以在不重新加载页面的情况下更新网页: 在页面已加载后从服务器请求数据: 在页面已加载后从服务器接收数据: 在后台向服务器发 ...

  7. idea intellij 混淆anroid代码

    idea intellij 混淆anroid代码 在project.properties中加入 target=android-14proguard.config=proguard.cfg 点击 Bui ...

  8. Spring 异常:Error creating bean with name

    异常信息:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxx' 我今 ...

  9. linux常用命令(二)

    文件处理命令接上一篇 cat concatenate and display fils 查看小文件 more分页显示文件 空格或者f翻页,回车下一行,Q或q退出. head –num  num代表行数 ...

  10. IIS7应用程序池集成和经典的区别

    IIS7应用程序池集成和经典的区别 IIS7应用程序池有集成和经典两种模式,根据微软官方的介绍, 集成模式,如果托管应用程序在采用集成模式的应用程序池中运行,服务器将使用 IIS 和 ASP.NET ...