[英]Should you use a partial class across projects?
我有一個包含所有數據庫邏輯的類庫。 我的DAL / BLL。
我有一些Web項目將使用相同的數據庫和類,所以我認為將數據層抽象到自己的項目中是一個好主意。
但是,當為某些項目的類添加功能時,我想向某些類添加方法。
例如,我的數據層有Product和SomeItem對象:
// Data Access Layer project
namespace DAL {
public class Product {
//implementation here
}
public class SomeItem {
//implementation here
}
}
在一個項目中,我想添加一個由不同內容項使用的接口,所以我有一個名為的類:
// This is in Web Project
namespace DAL {
public partial class Product : ICustomBehaviour {
#region ICustomBehaviour Implementation
TheSharedMethod();
#endregion
}
}
使用相同的命名空間在單獨的項目(創建依賴項)中編寫部分類是一個好主意嗎? 如果這是一個壞主意,我怎樣才能使這種類型的功能工作?
它似乎不想在編譯時合並它們,所以我不確定我做錯了什么。
您不能跨項目編寫部分類。 部分類是一個僅編譯時間的語法糖 - 整個類型最終在一個程序集中,即一個項目。
(順便說一下,你的原始DAL文件也必須聲明該類是部分的。)
部分類必須存在於同一個程序集中。 否則,編譯器將如何決定將部分類合並到哪里?
使用Visual Studio 2015及更高版本,可以跨項目拆分部分類:使用共享項目 (另請參閱此MSDN博客 )。
對於我的情況,我需要以下內容:
以下示例演示了部分類和共享項目如何允許在不同項目上拆分類。
在類庫中,Address.cs:
namespace SharedPartialCodeTryout.DataTypes
{
public partial class Address
{
public Address(string name, int number, Direction dir)
{
this.Name = name;
this.Number = number;
this.Dir = dir;
}
public string Name { get; }
public int Number { get; }
public Direction Dir { get; }
}
}
類庫是一個普通的Visual Studio類庫。 它導入了SharedProject,除此之外,它的.csproj不包含任何特殊內容:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<!-- standard Visual Studio stuff removed -->
<OutputType>Library</OutputType>
<!-- standard Visual Studio stuff removed -->
</PropertyGroup>
<!-- standard Visual Studio stuff removed -->
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Address.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="..\SharedProject\SharedProject.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Address.Direction
在SharedProject中實現:
namespace SharedPartialCodeTryout.DataTypes
{
public partial class Address
{
public enum Direction
{
NORTH,
EAST,
SOUTH,
WEST
}
}
}
SharedProject.shproj是:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>33b08987-4e14-48cb-ac3a-dacbb7814b0f</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="SharedProject.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
它的.projitems是:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>33b08987-4e14-48cb-ac3a-dacbb7814b0f</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>SharedProject</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Address.Direction.cs" />
</ItemGroup>
</Project>
常規客戶端使用Address
包括Address.Direction
:
using SharedPartialCodeTryout.DataTypes;
using System;
namespace SharedPartialCodeTryout.Client
{
class Program
{
static void Main(string[] args)
{
// Create an Address
Address op = new Address("Kasper", 5297879, Address.Direction.NORTH);
// Use it
Console.WriteLine($"Addr: ({op.Name}, {op.Number}, {op.Dir}");
}
}
}
常規客戶端csproj引用類庫而不是 SharedProject:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<!-- Removed standard Visual Studio Exe project stuff -->
<OutputType>Exe</OutputType>
<!-- Removed standard Visual Studio Exe project stuff -->
</PropertyGroup>
<!-- Removed standard Visual Studio Exe project stuff -->
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedPartialCodeTryout.DataTypes\SharedPartialCodeTryout.DataTypes.csproj">
<Project>{7383254d-bd80-4552-81f8-a723ce384198}</Project>
<Name>SharedPartialCodeTryout.DataTypes</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
DbSetup僅使用枚舉:
DbSetup.csproj不引用類庫; 它只導入SharedProject:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<!-- Removed standard Visual Studio Exe project stuff -->
<OutputType>Exe</OutputType>
<!-- Removed standard Visual Studio Exe project stuff -->
<?PropertyGroup>
<!-- Removed standard Visual Studio Exe project stuff -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="..\SharedProject\SharedProject.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
總結:
你能跨項目分割一個部分類嗎?
是的,使用Visual Studio的共享項目。
使用相同的命名空間在單獨的項目(創建依賴項)中編寫部分類是一個好主意嗎?
通常不會(見其他答案); 在某些情況下,如果你知道你在做什么,它可以很方便。
我認為這個方案沒有理由不起作用:
兩個文件包含存儲機制(或其他一些功能)。 它們指定繼承但不包含業務邏輯:
一個文件包含業務邏輯:
現在創建兩個項目:
兩個項目都使用相同的業務邏輯。
不可以。你不能在不同的項目中編寫部分類。因為在編譯器獲取單個項目進行編譯時,只掃描該項目中的類,方法,字段等列表。所以如果你有部分類的部分其他項目,編譯器無法找到那些。
我同意Jon Skeet的回答。
無論如何,我認為處理這樣的問題不是一個好的選擇。 有很好的設計模式已經證明了分割你的層/代碼層的最佳方法,這只是一點點語法糖,因此微軟可以將WinForms / WebForms設計器文件分開,防止人們破壞它們。
雖然在談到pre-linq開發時我同意你的意見,但我也希望我能夠做到這一點,以便將業務邏輯從Linq2SQL設計器生成的部分類中分離出來。 例如:
Northind.DAL (prj)
-NorthindDataContext (EntityNamespace set to "Northwind.BLL")
--Product() (Entity, partial class auto-generated)
--Category() (Entity, partial class auto-generated)
--Supplier() (Entity, partial class auto-generated)
Northind.BLL (prj)
-Product() : IMyCustomEnityInterface, BaseEntity (override OnValidate(), etc)
-Category() : IMyCustomEnityInterface, BaseEntity (override OnValidate(), etc)
-Supplier() : IMyCustomEnityInterface, BaseEntity (override OnValidate(), etc)
不幸的是,我們無法做到這一點......實際上,我很想知道在使用LINQ時分割圖層/層的推薦方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.