WCF自身功能特别强大,目前也是学习阶段。其实ADO抽象出来的BLL层自身就相当于现在的wcf的服务层。最初也是尝试阶段,所以写的代码也比较混乱,但是基本功能实现了。不过还有很多需要去完善的,比方说错误异常处理,日志记录这些都没做。
项目结构:
一、首先是针对Model层的生成,我采用的是EF自动生成:
①因为这样有利于数据的维护,以及数据表过多,写数据表费劲。
②利用T4模板生成很多重复的代码,这样减少压力
首先建一个类库,然后新建项的时候选择数据,然后选ado.net实体对象。具体的不写了,可以去看如何使用EF生成model实体的,很简单。结果图:
二、common层介绍,ado数据库操作类比较多,百度一个就行了。
本来想拓展个日志类的,但是技术有限一直没能拓展完成,不过跟一会的dal层引用原理其实是一样的。
三、DAL层介绍
DAL层用接口的形式实现,目的是为了使用不同的DAL实现,ado只是其中一种,另外就是用EF实现。。但是EF结合wcf的时候会报错,因为IQueryable是不支持序列化。或者可以TOLIST来解决吧,我没尝试。
DAL里面四层,但是EFDAL没写。adodal是IDAL的具体实现。
1、IDAL里面抽象出来一个IBaseDal,其他的接口都继承这个即可。
2、其他接口用T4模板生成,具体的如何用T4模板生成,其他地方做介绍,或者百度:
点开一个看看包含的内容:很简单,啥也没的,哈哈
IDbSession是静态工厂接口,实现类,其实精髓还是在于StaticFactory,这是跟一个大佬学的,我觉如果把这个学好了,对于拓展软件的功能,有很大的帮助,就看你会不会抽象了。根据配置的命名空间不同,去不同的dal做操作,这个跟nspring里面基于配置实现是一个道理的,结合的很好。
这个DbSessionFactory是个单例
adoDal:adodal也是一个basedal,并不继承Ibasedal因为他两个没有必然的联系,basedal是抽象dal的共同的东西罢了,不过并没有具体的东西。因为这个项目是我从EFDal改来的,所以为了兼容保留了basedal。主要原因就是因为adonet需要些sql语句,ef不用sql语句就能实现。不过这种用参数注入的方式不安全。其他不列了有基础的都搞的定。
四、BLL层正式登场,其实DAL写的牛,BLL层其实啥也没的,就是调用DAl层。
Ext是登录的拓展,后续有其他方法都在这个里面拓展。
服务,这个baseservice就完全的实现了里面所有的内容:
public abstract class BaseService<T> where T : class ,new()
{
//创建日志记录组件实例
ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// 初始化service的时候,初始化当前dal
/// </summary>
public IBaseDal<T> CurrentDal { get; set; }
/// <summary>
/// 在构造函数中实现父类的方法
/// </summary>
public BaseService()
{
SetCurrentDal();
}
/// <summary>
/// 获取dal的单例工厂
/// </summary>
public IDbSession Dbsession
{
get { return DbSessionFactory.GetCurrentDbSession(); }
}
//创建一个抽象方法,逼迫子类必须实现
public abstract void SetCurrentDal();
public System.Data.DataSet GetList(T entity)
{
return CurrentDal.GetList(entity);
}
public System.Data.DataSet QueryList()
{
return CurrentDal.QueryList();
}
public int Add(T entity)
{
return CurrentDal.Add(entity);
}
public bool Update(T model)
{
return CurrentDal.Update(model);
}
public bool Delete(int DId)
{
return CurrentDal.Delete(DId);
}
public bool DeleteList(string DIdlist)
{
return CurrentDal.DeleteList(DIdlist);
}
public T GetModel(int DId)
{
return CurrentDal.GetModel(DId);
}
public System.Data.DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex)
{
return CurrentDal.GetListByPage(strWhere, orderby, startIndex, endIndex);
}
}
其他服务就简单多了:
五、寄宿采用IIS,然后用自身寄宿调试,不然代码有错很头大,自身寄宿调试好,然后放IIS跑,就行了。如何部署项目到IIS,可以看其他文章介绍:
WcfServiceTest这个很简单的,就是添加了一个wcf服务应用程序。把默认的删了,自己修改下就行了。
ManagerInfoService.scv里面就这个东西:
<%@ ServiceHost Language="C#" Debug="true" Service="MengGe.Cater.BLL.ManagerInfoService" %>
web内容介绍:
<?xml version="1.0"?>
<configuration>
<!--
有关 web.config 更改的说明,请参见 http://go.microsoft.com/fwlink/?LinkId=235367。
可在 <httpRuntime> 标记上设置以下特性。
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
<appSettings>
<add key="conn" value="server=192.168.10.10;database=MengGe.Cater;uid=sa;pwd=admin123"/>
<add key="DataType" value="SqlServer"/>
<!--抽象工厂创建数据库访问层实例所在的程序集名称-->
<add key="DalAssemblyName" value="MengGe.Cater.AdoDal" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<services>
<service name="MengGe.Cater.BLL.DishInfoService" behaviorConfiguration="myBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8823/Services"/>
</baseAddresses>
</host>
<endpoint address="DishInfoService"
binding="basicHttpBinding"
contract="MengGe.Cater.IBLL.IDishInfoBll"/>
</service>
<service name="MengGe.Cater.BLL.ManagerInfoService" behaviorConfiguration="myBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8823/Services"/>
</baseAddresses>
</host>
<endpoint address="ManagerInfoService"
binding="basicHttpBinding"
contract="MengGe.Cater.IBLL.IManagerInfoBll"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
六、客户端winform实现:
很简单的不多介绍,直接介绍wcf的内容,首先为了懒省事,我直接添加的web服务引用
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IManagerInfoBll" />
</basicHttpBinding>
</bindings>
<client>
<!---->
<!--http://localhost:8823/Services/ManagerInfoService-->
<endpoint address="http://192.168.10.2/ManagerInfoService.svc/ManagerInfoServic"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IManagerInfoBll"
contract="Services.IManagerInfoBll" name="BasicHttpBinding_IManagerInfoBll" />
</client>
</system.serviceModel>
</configuration>
界面不做介绍,直接看登录按钮实现:
public partial class FrmLogin : Skin_VS
{
public FrmLogin()
{
InitializeComponent();
}
ManagerInfoBllClient miClient = new ManagerInfoBllClient();
private void FrmLogin_Load(object sender, EventArgs e)
{
}
private void btnCancel_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnLogin_Click(object sender, EventArgs e)
{
ManagerInfo mi = new ManagerInfo();
mi.MName = txtUserName.Text;
mi.MPwd = txtPassword.Text;
if (miClient.Login(mi))
{
FrmMain frmMain= FormFactory.CreateFrmMain();
frmMain.mi = mi;
frmMain.Show();
this.Visible = false;
}
else
{
MessageBox.Show("用户名或密码错误");
}
}
}
大致就介绍完了,代码下载: