很多项目都需要具备支持多种数据库的能力。在实现的时候,我采用的方式是使用同名数据库实现层覆盖的方式。具体如下:
数据接口层: Stock.IRepository
数据实现层: Stock.Repository : Stock.IRepository.
目前数据接口层有两个版本的实现,一个是SQL Server , 一个是Oracle, 编译后生成的dll名字都是Stock.Repository.dll.
这样就带来一个问题,如果通过添加项目引用的方式,业务层一次只能引用一种数据实现层dll,这样开发和调试非常不方便。经过摸索,结合Solution配置和MsBuild的功能,达到了根据配置自动切换引用的目标。
假定解决方案结构如下:
Stock Solution
--Stock.IRepository
--Stock.Repository > SQLServer版本,生成Stock.Repository.dll.
--Stock.Repository.Oracle > Oracle版本,生成Stock.Repository.dll.
--Stock.Services > 业务层,需要通过项目引用Stock.Repository或Stock.Repository.Oracle
--Stock.WebUI
第一步: 新建解决方案配置
点击菜单上的 生成(B) > 配置管理器(O)..., 在打开的窗口上,点击活动解决方案配置,分别以Debug/Release模式新建Stock Oracle Debug, Stock Oracle Release两种配置。
选择Stock Oracle Debug, 仅保留Stock.Services / Stock.WebUI 的配置为Stock Oracle Debug, 其它的都改为Debug.
选择Stock Oracle Release, 仅保留Stock.Services / Stock.WebUI的配置为Stock Release Debug, 其它的都改为Release.
第二步: 编辑项目文件
手动打开Stock.Services.csproj,编辑它的内容,在<project>节点下面添加下面的xml片段。
<Choose> <When Condition=" ‘$(Configuration)|$(Platform)‘ == ‘Stock Oracle Debug|AnyCPU‘ Or ‘$(Configuration)|$(Platform)‘ == ‘Stock Oracle Release|AnyCPU‘ "> <ItemGroup> <ProjectReference Include="..\Stock.Repository.Oracle\Stock.Repository.Oracle.csproj"> <Project>{3429B848-F3C5-464A-B7CB-A59C8EECB772}</Project> <Name>Stock.Repository.Oracle</Name> </ProjectReference> </ItemGroup> </When> <Otherwise> <ItemGroup> <ProjectReference Include="..\Stock.Repository\Stock.Repository.csproj"> <Project>{CD0A2673-6773-4FEB-B286-ED08BA6F7EF2}</Project> <Name>Stock.Repository</Name> </ProjectReference> </ItemGroup> </Otherwise> </Choose>
代码很清楚,就不详细说明了。
如果需要在编译完成后,自动执行一些特定任务。比如分别使用不同的Web.Config文件, 或者将生成的dll复制到不同目录等,可以参考下面的做法。手动修改Stock.WebUI.csproj文件,编辑它的内容,在<project>节点下面添加下面的xml片段:
<Choose> <When Condition=" ‘$(Configuration)|$(Platform)‘ == ‘Stock Oracle Debug|AnyCPU‘ Or ‘$(Configuration)|$(Platform)‘ == ‘Stock Oracle Release|AnyCPU‘ "> <PropertyGroup> <PostBuildEvent> echo "Stock Oracle verison Begin." xcopy "$(TargetDir)\Stock.*.dll" "$(SolutionDir)..\Reference\Stock\" /Y/C/E/F/R echo "All Stock dll has coied to ..\..\Reference\Stock\." xcopy "$(TargetDir)\Stock.Repository.*" "$(SolutionDir)..\Reference\Stock Repository(Oracle)\" /Y/C/E/F/R echo "Stock Oracle Repository dll has copied to ..\..\Stock Repository(SQLServer)\." attrib -R "$(ProjectDir)\web.config" copy "$(ProjectDir)\web.Oracle.config" "$(ProjectDir)\web.config" echo "Stock web.Oracle.config overide web.config OK." echo "Stock Oracle verison OK." </PostBuildEvent> </PropertyGroup> </When> <Otherwise> <PropertyGroup> <PostBuildEvent> echo "Stock SQLServer verison Begin." xcopy "$(TargetDir)\Stock.*.dll" "$(SolutionDir)..\Reference\Stock\" /Y/C/E/F/R echo "All Stock dll has coied to ..\..\Reference\Stock\." xcopy "$(TargetDir)\Stock.Repository.*" "$(SolutionDir)..\Reference\Stock Repository(SQLServer)\" /Y/C/E/F/R echo "Stock SQLServer Repository dll has copied to ..\..\Stock Repository(SQLServer)\." attrib -R "$(ProjectDir)\web.config" copy "$(ProjectDir)\web.SQLServer.config" "$(ProjectDir)\web.config" echo "Stock web.SQLServer.config overide web.config OK." echo "Stock SQLServer verison OK." </PostBuildEvent> </PropertyGroup> </Otherwise> </Choose>