WedeNet2018.WedeWcfServices-WCF服务层:
结构如下:

就是定义了服务契约接口和服务类,以OrderServices为例,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using WedeNet2018.Infrastructure;
using WedeNet2018.Infrastructure.WcfEntities; namespace WedeNet2018.WedeWcfServices
{
[ServiceContract]
public interface IOrderServices
{
[OperationContract]
OrdersContract[] GetOrders(int orderType);
[OperationContract]
OrdersContract GetOrdersStr(int orderType);
[OperationContract]
void AddOrder(OrdersContract order);
[OperationContract]
void UpdateOrder(OrdersContract order);
[OperationContract]
void DeleteOrder(int id);
}
}

实现类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using WedeNet2018.Infrastructure;
using WedeNet2018.BussinessLogic;
using Ninject;
using WedeNet2018.Infrastructure.Components;
using SFast;
using WedeNet2018.Infrastructure.WcfEntities; namespace WedeNet2018.WedeWcfServices.Impl
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class OrderServices : IOrderServices
{ private OrdersBussinessLogic orderBll { get; set; }
public OrderServices() {
IKernel ninjectKernel = new StandardKernel();
ninjectKernel.Bind<AbsWedeDBContex>().To<WedeDBContex>();
ninjectKernel.Bind<IWedeUnitOfWorks>().To<WedeUnitOfWorks<AbsWedeDBContex>>().InSingletonScope();
ninjectKernel.Bind<OrdersBussinessLogic>().ToSelf();
orderBll = ninjectKernel.Get<OrdersBussinessLogic>();
} public OrdersContract[] GetOrders(int orderType)
{ OrdersContract[] ret = null;
try
{
IList<Orders> orders = orderBll.GetOrders(orderType).ToList();
IList<OrdersContract> ordersContracts = new List<OrdersContract>();
orders.ForEach(o => ordersContracts.Add(new OrdersContract() { Id=o.Id,OrderSn=o.OrderSn}));
ret = ordersContracts.ToArray();
}
catch (Exception ex)
{ }
return ret;
} public OrdersContract GetOrdersStr(int orderType)
{ OrdersContract ret = new OrdersContract();
try
{
Orders order = orderBll.GetOrders(orderType).FirstOrDefault();
if (order != null) {
ret.Id = order.Id;
ret.OrderSn = order.OrderSn;
} }
catch (Exception ex)
{ }
return ret;
} public void AddOrder(OrdersContract order) { } public void UpdateOrder(OrdersContract order) { } public void DeleteOrder(int id) { }
}
}

这里需要说明的是,服务实现类的构造函数里,也有NInject的映射配置,当然这里是按需配置的。

WedeNet2018.ServiceHosting-WCF服务寄宿层:
结构如下:

(需要说明的是,本层是一个windows服务)

服务寄宿层的App.config里配置WCF相关配置信息,如:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ValidServices"
type="WedeNet2018.ServiceHosting.ValidServicesSection, WedeNet2018.ServiceHosting" />
</configSections>
<connectionStrings>
<add name="constring" connectionString="Data Source=.;Initial Catalog=MVCEF1;User ID=sa;Password=11111111;" providerName="System.Data.SqlClient" />
<add name="xf0816Constring" connectionString="Data Source=172.18.105.63;Initial Catalog=Xinfu0816;User ID=test;Password=xinfuka;" providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<ValidServices>
<Services>
<add Type="WedeNet2018.WedeWcfServices.Impl.OrderServices,WedeNet2018.WedeWcfServices" />
<add Type="WedeNet2018.WedeWcfServices.Impl.UserServices,WedeNet2018.WedeWcfServices" />
</Services>
</ValidServices>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="endpointBehavior">
<dataContractSerializer />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="WedeNetServerBehavior_order">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:9999/WedeWcfServices/orderServices/metadata" />
<serviceDebug httpHelpPageEnabled="true" httpsHelpPageEnabled="true"
includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="WedeNetServerBehavior_user">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:9999/WedeWcfServices/userServices/metadata" />
<serviceDebug httpHelpPageEnabled="true" httpsHelpPageEnabled="true"
includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WedeWcfBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="99965536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WedeNetServerBehavior_order" name="WedeNet2018.WedeWcfServices.Impl.OrderServices">
<endpoint address="http://localhost:9999/WedeWcfServices/orderServices"
behaviorConfiguration="endpointBehavior" binding="wsHttpBinding"
bindingConfiguration="WedeWcfBinding" contract="WedeNet2018.WedeWcfServices.IOrderServices">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
<service behaviorConfiguration="WedeNetServerBehavior_user" name="WedeNet2018.WedeWcfServices.Impl.UserServices">
<endpoint address="http://localhost:9999/WedeWcfServices/userServices"
behaviorConfiguration="endpointBehavior" binding="wsHttpBinding"
bindingConfiguration="WedeWcfBinding" contract="WedeNet2018.WedeWcfServices.IUserServices">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
</system.serviceModel>
</configuration>

ValidServices配置节点是批量寄宿服务时,读取配置的服务信息的,其实现如下:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace WedeNet2018.ServiceHosting
{
/// <summary>
/// Custom configuration section for valid service setting
/// </summary>
internal class ValidServicesSection : ConfigurationSection
{
[ConfigurationProperty("Services")]
public ValidServiceCollection ValidServices
{
get { return this["Services"] as ValidServiceCollection; }
}
} /// <summary>
/// Custom configuration element collection for valid service setting
/// </summary>
internal class ValidServiceCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new ValidService();
} protected override object GetElementKey(ConfigurationElement element)
{
return ((ValidService)element).Type;
}
} /// <summary>
/// Custom configuration element for valid service setting
/// </summary>
internal class ValidService : ConfigurationElement
{
[ConfigurationProperty("Type")]
public string Type
{
get
{
return (string)this["Type"];
}
}
}
}

ServiceManager类:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using WedeNet2018.Common; namespace WedeNet2018.ServiceHosting
{
internal class ServiceManager
{
/// <summary>
/// Container for all valid services
/// </summary>
static List<ServiceHost> _AllHosts = new List<ServiceHost>(); /// <summary>
/// Start all valid services.
/// </summary>
public static void StartAllValidServices()
{
string entryLocation = Assembly.GetEntryAssembly().Location; Configuration conf = ConfigurationManager.OpenExeConfiguration(entryLocation); ValidServicesSection validServiceSettings
= ConfigurationManager.GetSection("ValidServices") as ValidServicesSection; if (validServiceSettings != null)
{
foreach (ValidService validService in validServiceSettings.ValidServices)
{
string typeToLoad = validService.Type;
LoggerHelper.ServicesLogger.Info("typeToLoad:" + typeToLoad);
// Load the assembly dynamic
string assemblyName = typeToLoad.Substring(typeToLoad.IndexOf(',') + 1);
LoggerHelper.ServicesLogger.Info("assemblyName:" + assemblyName);
Assembly.Load(assemblyName); Type svcType = Type.GetType(typeToLoad);
if (svcType == null)
{
string errInfo = string.Format("Invalid Service Type \"{0}\" in configuration file.",
typeToLoad); LoggerHelper.ServicesLogger.Info(errInfo);
throw new ApplicationException(errInfo);
}
else
{
OpenHost(svcType);
}
}
}
else
{
throw new ApplicationException("Application configuration for WCF services not found!");
}
} /// <summary>
/// Create a host for a specified wcf service;
/// </summary>
/// <param name="t"></param>
private static void OpenHost(Type t)
{
ServiceHost host = new ServiceHost(t); host.Opened += new EventHandler(hostOpened);
host.Closed += new EventHandler(hostClosed);
host.Open(); _AllHosts.Add(host);
} /// <summary>
/// Close all services
/// </summary>
public static void CloseAllServices()
{
foreach (ServiceHost host in _AllHosts)
{
if (host.State != CommunicationState.Closed)
{
host.Close();
}
}
} /// <summary>
/// Event handler for host opened
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void hostOpened(object sender, EventArgs e)
{
ServiceDescription svcDesc = ((ServiceHost)sender).Description; string svcName = svcDesc.Name;
StringBuilder allUri = new StringBuilder();
foreach (ServiceEndpoint endPoint in svcDesc.Endpoints)
{
allUri.Append(endPoint.ListenUri.ToString());
} LoggerHelper.ServicesLogger.Info(string.Format("Service \"{0}\" started with url: {1}",
svcName, allUri.ToString()));
} /// <summary>
/// Event handler for host closed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void hostClosed(object sender, EventArgs e)
{
ServiceDescription svcDesc = ((ServiceHost)sender).Description; string svcName = svcDesc.Name; LoggerHelper.ServicesLogger.Info(string.Format("Service \"{0}\" stopped.", svcName));
}
}
}

实现批量服务寄宿的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using WedeNet2018.Common;
using WedeNet2018.WedeWcfServices.Impl; namespace WedeNet2018.ServiceHosting
{
public partial class WedeNet2018Services : ServiceBase
{
static List<ServiceHost> _allHosts = new List<ServiceHost>();
public WedeNet2018Services()
{
InitializeComponent();
} protected override void OnStart(string[] args)
{
try
{
ServiceManager.StartAllValidServices();
LoggerHelper.ServicesLogger.Info("All WCF services started.");
}
catch (ApplicationException ex)
{
LoggerHelper.ServicesLogger.Info(ex.Message);
}
} protected override void OnStop()
{
try
{
ServiceManager.CloseAllServices();
LoggerHelper.ServicesLogger.Info("All WCF services stopped.");
}
catch (ApplicationException ex)
{
LoggerHelper.ServicesLogger.Info(ex.Message);
}
}
}
}

最后,服务的安装和卸载.bat代码:
service_install.bat

@echo off
set /p var=是否要安装 WCF 服务(Y/N):
if "%var%" == "Y" (goto install) else (goto batexit) :install
copy C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe InstallUtil.exe /Y
call InstallUtil.exe E:\个人\Wede框架\WedeNet2018\WedeNet2018\WedeNet2018.ServiceHosting\bin\Debug\WedeNet2018.ServiceHosting.exe
call sc start "WedeNet2018Services"
pause :batexit
exit

service_unInstall.bat

@echo off
set /p var=是否要卸载 WCF服务(Y/N):
if "%var%" == "Y" (goto uninstall) else (goto batexit) :uninstall
copy C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe InstallUtil.exe /Y
call InstallUtil.exe /u E:\个人\Wede框架\WedeNet2018\WedeNet2018\WedeNet2018.ServiceHosting\bin\Debug\WedeNet2018.ServiceHosting.exe
pause :batexit
exit

搭建自己的框架WedeNet(五)的更多相关文章

  1. 搭建自己的框架WedeNet(一)

    框架用到的技术: EF.UnitOfWork+Repository.Ninject.log4net.WCF.MVC.T4.windows服务.AOP前端技术:Bootstrap.layer.jQuer ...

  2. 搭建自己的框架WedeNet(四)

    WedeNet2018.Web-UI层:结构如下: 首先,在Controller中定义BaseController,以便加入统一处理逻辑,如下: using log4net; using System ...

  3. 搭建自己的框架WedeNet(三)

    WedeNet2018.BussinessLogic-业务逻辑层:结构如下: 基类: using System; using System.Collections.Generic; using Sys ...

  4. 搭建自己的框架WedeNet(二)

    WedeNet2018.Infrastructure-基础设施层:结构如下: Tools结构如下: 考虑到系统可能会有多个数据上下文(暂时以两个为例),所以根据需要定义两个T4模板用来生成对应的ent ...

  5. Web前端-Vue.js必备框架(五)

    Web前端-Vue.js必备框架(五) 页面组件,商品列表组件,详情组件,购物车清单组件,结算页组件,订单详情组件,订单列表组件. vue-router 路由 vuex 组件集中管理 webpack ...

  6. 从零开始学 Java - 搭建 Spring MVC 框架

    没有什么比一个时代的没落更令人伤感的了 整个社会和人都在追求创新.进步.成长,没有人愿意停步不前,一个个老事物慢慢从我们生活中消失掉真的令人那么伤感么?或者说被取代?我想有些是的,但有些东西其实并不是 ...

  7. Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED

    Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED Xvfb+YSlow+ShowSlow搭建前端性能测试框架 作者:黑三 | 时间:2010-07-07 ...

  8. Windows环境搭建Web自动化测试框架Watir

    Windows环境搭建Web自动化测试框架Watir 一.前言     Web自动化测试一直是一个比较迫切的问题,对于现在web开发的敏捷开发,却没有相对应的敏捷测试,故开此主题,一边研究,一边将We ...

  9. 搭建App主流框架_纯代码搭建(OC)

    转载自:http://my.oschina.net/hejunbinlan/blog/529778?fromerr=EmSuX7PR 搭建主流框架界面 源码地址在文章末尾 达成效果 效果图 注:本文部 ...

随机推荐

  1. MySQL:行锁、表锁、乐观锁、悲观锁、读锁、写锁

    1.锁的分类 1.1从对数据操作的类型来分 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响. 结论1: --如果某一个会话 对A表加了read锁,则 该会话 可以对A表进行读操作 ...

  2. mysql查询json字段

    一张test表里存了一个content字段是json类型的,查询该content里manualNo这个字段 select JSON_EXTRACT (test .content, '$.manualN ...

  3. JavaScript中字符串,数组的基本操作

    JavaScript的字符串就是用”或”“括起来的字符表示. js中操作字符串: 1.获得字符串的长度 var s = 'Hello, world!'; s.length; // 132.获取指定字符 ...

  4. RabbitMQ学习之:(十)AMQP和RabbitMQ介绍 (转贴+我的评论)

    From: http://www.infoq.com/cn/articles/AMQP-RabbitMQ 准备开始 高级消息队列协议(AMQP1)是一个异步消息传递所使用的应用层协议规范.作为线路层协 ...

  5. delphi stringgrid导出为excel

    procedure TLiYQBYJL.btnBYJLTJDCClick(Sender: TObject); var ExcelApp, workbook, sheet: Variant; col, ...

  6. vue项目报错:Unexpected tab character (no-tabs)

    eslint意思是检查规范代码 第一种方法: 新建项目的时候 第二种方法: 首先在项目的根目录下.eslintrc.js中加入一行代码:"no-tabs":"off&qu ...

  7. Vue 子组件与子组件之间传值

    可以借用公共父元素.子组件A  this.$emit("eventName", data) 触发事件,父组件监听事件,更改父组件 data , 通过Props 传值到子组件B,子组 ...

  8. NetCore 对Json文件的读写操作

    nuget Microsoft.Extensions.Configuration; Microsoft.Extensions.Configuration.Json; Newtonsoft.Json; ...

  9. 函数节流之debounce

    浏览器中某些计算和处理要比其他的昂贵很多.例如, DOM 操作比起非 DOM 交互需要更多的内存和 CPU 时间.连续尝试进行过多的 DOM 相关操作可能会导致浏览器挂起,有时候甚至会崩溃.尤其在 I ...

  10. 截取铃声python代码

    from pydub import AudioSegment file_name = "张杰 - 这就是爱.mp3" sound = AudioSegment.from_mp3(f ...