很多項目都需要具備支持多種數據庫的能力。在實現的時候,我採用的方式是使用同名數據庫實現層覆蓋的方式。具體如下:
數據接口層: 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>