最近,工作之余学习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. ViewPager图片切换的简单案例

    1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类. 2)ViewPager类需要一个PagerAdapter适配器类给它提供数据. 向右滑动切 ...

  2. RUDP之三 —— Virtual Connection over UDP

    原文链接 原文:http://gafferongames.com/networking-for-game-programmers/virtual-connection-over-udp/ Introd ...

  3. C++: virtual inheritance and Cross Delegation

    Link1: Give an example Note: I think the Storable::Write method should also be pure virtual. http:// ...

  4. bzoj 3791: 作业

    Description 众所周知,白神是具有神奇的能力的. 比如说,他对数学作业说一声“数”,数学作业就会出于畏惧而自己完成:对语文作业说一声“语”,语文作业就会出于畏惧而自己完成. 今天,语文老师和 ...

  5. tornado 学习笔记8 模板以及UI

          Tornado 包含一个简单.快速而且灵活的模板语言.       Tornado同样可以使用任何其他的python模板语言,虽然没有集成这些模板语言进RequestHandler.ren ...

  6. ZeroMQ接口函数之 :zmq_connect - 由一个socket创建一个对外连接

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_connect zmq_connect(3)  ØMQ Manual - ØMQ/3.2.5 Name zmq_c ...

  7. About_Return

    返回值:return return 表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值,由return后面的参数指定. return通常是必要的,因为函数调用的时候计算结果通常是通过返回值带 ...

  8. 01 LabVIEW的类中各个Scope的范围

    范例地址: D:\Program Files (x86)\National Instruments\LabVIEW 2015\examples\Object-Oriented Programming\ ...

  9. vim基本命令

    vim基本命令     1.vim#在命令行中输入vim,进入vim编辑器2.i#按一下i键,下端显示 --INSERT--#插入命令,在vim中可能任意字符都有作用3.Esc#退出i(插入)命令进行 ...

  10. HTML基础篇之列表相关标签和特殊字符实体

    HTML字符实体 常用的字符实体: 实体字符 字符实体 大于号 (>) > 小于号 (<) < 引号 (") " 注册商标(®) ® 版权(© ) © &a ...