最近在项目中多次应用了windows服务,主要是用来作为WCF宿主和监控数据库的数据变化。发现其实windows服务并不需要每个服务都要新建一个项目,每次都设置服务信息。使用接口和设计模式中的工厂模式,一劳永逸。首先提供一个IService接口,在windows服务中通过ServiceFactory构造实现IService方法的类。wcfHost实现IService,代码如下:
//windows服务中的方法。
IService service = null;
protected override void OnStart(string[] args)
{
try
{
//构造服务接口
service = IService.ServiceFactory.CreateServiceMethod();
service.Start();
}
catch (Exception ex)
{
SeatManage.SeatManageComm.WriteLog.Write(string.Format("服务启动失败:异常来自:{0};异常信息:{1}", ex.Source, ex.Message));
}
}
/// <summary>
/// windows服务接口
/// </summary>
public interface IService : System.IDisposable
{
/// <summary>
/// 开始服务
/// </summary>
void Start();
/// <summary>
/// 结束服务
/// </summary>
void Stop();
}
同一个程序集中包含一个工厂类,可以通过该工厂创建任意的wcf服务。代码如下:
/// <summary>
/// 服务构造工厂
/// </summary>
public class ServiceFactory
{
/// <summary>
/// 构造服务对象
/// </summary>
/// <returns></returns>
public static IService CreateServiceMethod()
{
string assemblyType = ConfigurationManager.AppSettings["ServiceAssembly"];
if (!string.IsNullOrEmpty(assemblyType))
{
try
{
//通过反射构造服务接口实现的程序集
IService obj = (IService)createInferface(assemblyType);
return obj;
}
catch (Exception ex)
{
throw new Exception("构建服务接口失败:" + ex.Message);
}
}
else
{
throw new Exception("没有服务接口");
}
}
private static object createInferface(string assembly)
{
if (!string.IsNullOrEmpty(assembly))
{
try
{
string[] type = assembly.Split(',');
if (type.Length == 0)
{
throw new Exception("接口实现配置错误");
}
return Assembly.Load(type[1]).CreateInstance(type[0]);
}
catch (Exception ex)
{
throw ex;
}
}
else
{
throw new Exception("没有配置接口实现的相关信息");
}
}
}
然后实现IService接口,
public class Service: IService.IService
{
public void Start()
{
//添加实现方法
}
public void Stop()
{
//添加实现方法
}
}
最后在config文件的appsettings节点中添加程序集信息就可以了。我这里是添加这个节点:
<!--服务接口程序集信息 value值: 逗号前为类的命名空间+类名称,后面为程序集名称--> <add key="ServiceAssembly" value="SeatService.Service.SeatWatch,SeatService.Service"/>
这样设计的好处:
1.方便:通过接口隔离windows服务和具体实现,降低耦合。调试时不需要反复卸载监控服务,更新方便,直接拷贝实现接口的程序集就可以。不需要卸载服务再安装。自然也不用担心因为卸载windows服务出现异常导致服务卸载失败了。
2.扩展性:如果是需要实现其他的服务,只需要替换实现接口的程序集。该方法只提供一个服务。如果想要在一个windows服务上提供多个服务。可以通过配置文件添加需要提供服务的接口信息,通过反射把接口实现的类构造后放到类型为List<IService>的对象中,在windows中遍历启动即可。
PS:本人拙见,有不足还请指正,不喜勿喷。