แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้แอสเซมบลีแอสเซมบลีคืออะไร


163

ฉันมีทางออกสำหรับหลาย ๆ โครงการ ฉันกำลังพยายามเพิ่มประสิทธิภาพไฟล์ AssemblyInfo.cs โดยการเชื่อมโยงหนึ่งไฟล์ข้อมูลประกอบกว้างโซลูชั่น อะไรคือแนวทางปฏิบัติที่ดีที่สุดสำหรับการทำสิ่งนี้? แอ็ตทริบิวต์ใดที่ควรอยู่ในไฟล์โซลูชันกว้างและเฉพาะโครงการ / ชุดประกอบ


แก้ไข: หากคุณสนใจมีคำถามติดตามสิ่งที่แตกต่างระหว่าง AssemblyVersion, AssemblyFileVersion และ AssemblyInformationalVersion คืออะไร?

คำตอบ:


207

เรากำลังใช้ไฟล์ทั่วโลกชื่อ GlobalAssemblyInfo.cs และไฟล์ในท้องที่ที่เรียกว่า AssemblyInfo.cs ไฟล์ทั่วโลกมีคุณสมบัติดังต่อไปนี้:

 [assembly: AssemblyProduct("Your Product Name")]

 [assembly: AssemblyCompany("Your Company")]
 [assembly: AssemblyCopyright("Copyright © 2008 ...")]
 [assembly: AssemblyTrademark("Your Trademark - if applicable")]

 #if DEBUG
 [assembly: AssemblyConfiguration("Debug")]
 #else
 [assembly: AssemblyConfiguration("Release")]
 #endif

 [assembly: AssemblyVersion("This is set by build process")]
 [assembly: AssemblyFileVersion("This is set by build process")]

AssemblyInfo.cs ภายในเครื่องประกอบด้วยแอตทริบิวต์ต่อไปนี้:

 [assembly: AssemblyTitle("Your assembly title")]
 [assembly: AssemblyDescription("Your assembly description")]
 [assembly: AssemblyCulture("The culture - if not neutral")]

 [assembly: ComVisible(true/false)]

 // unique id per assembly
 [assembly: Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]

คุณสามารถเพิ่ม GlobalAssemblyInfo.cs โดยใช้ขั้นตอนต่อไปนี้:

  • เลือกเพิ่ม / รายการที่มีอยู่ ...ในเมนูบริบทของโครงการ
  • เลือก GlobalAssemblyInfo.cs
  • ขยายปุ่มเพิ่มโดยคลิกที่ลูกศรชี้ลงทางขวามือ
  • เลือก "เพิ่มเป็นลิงค์" ในรายการแบบหล่นลงของปุ่ม

จุดประสงค์ของการเก็บไฟล์ AssemblyInfo.cs เก่าไว้คืออะไร เมื่อฉันสร้างแสตมป์รุ่นบิลด์ใน GlobalAssemblyInfo.cs โดยอัตโนมัติสิ่งนั้นจะอัปเดตไฟล์ AssemblyInfo.cs ที่ฉันมีในโซลูชันของฉันอย่างไร
D3vtr0n

3
@Devtron ไฟล์ AssemblyInfo แต่ละไฟล์ควรให้ข้อมูลที่ไม่ซ้ำกับแอสเซมบลีที่อยู่ในนั้น (เช่นชื่อคำอธิบายและวัฒนธรรมตามที่แสดงไว้ในตัวอย่างด้านบน) รายการทั่วไปเช่นชื่อผลิตภัณฑ์และข้อมูลเวอร์ชันควรถูกลบออก (และจะทำให้เกิดข้อผิดพลาดของคอมไพเลอร์หากมีการทำซ้ำ) ในอุดมคติแล้วไฟล์ AssemblyInfo จะไม่ถูกอัพเดตโดยกระบวนการบิลด์
David Keaveny

1
AssemblyCultureAttributeสมควรได้รับเป็นคำอธิบายที่ดีกว่า แอตทริบิวต์ที่ดีที่สุดควรจะขาดไปอย่างสมบูรณ์ (ยกเว้นกรณีนี้เป็นชุดดาวเทียม) เมื่อใช้แอสเซมบลีดาวเทียมในขนาดใหญ่หนึ่งอาจต้องสามไฟล์ไฟล์แอสเซมบลีไม่สองระดับ (ส่วนกลางแอสเซมบลีหลักและแอสเซมบลีดาวเทียมซึ่งระบุวัฒนธรรมในกรณีนี้เท่านั้น)
Jirka Hanika

20

ในกรณีของฉันเรากำลังสร้างผลิตภัณฑ์ที่เรามีโซลูชัน Visual Studio โดยมีส่วนประกอบต่าง ๆ ในโครงการของตนเอง คุณลักษณะทั่วไปจะเป็นไป ในโซลูชันมีโครงการประมาณ 35 โครงการและข้อมูลประกอบทั่วไป (CommonAssemblyInfo.cs) ซึ่งมีแอตทริบิวต์ดังต่อไปนี้:

[assembly: AssemblyCompany("Company")]
[assembly: AssemblyProduct("Product Name")]
[assembly: AssemblyCopyright("Copyright © 2007 Company")]
[assembly: AssemblyTrademark("Company")]

//This shows up as Product Version in Windows Explorer
//We make this the same for all files in a particular product version. And increment it globally for all projects.
//We then use this as the Product Version in installers as well (for example built using Wix).
[assembly: AssemblyInformationalVersion("0.9.2.0")]

คุณลักษณะอื่น ๆ เช่น AssemblyTitle, AssemblyVersion ฯลฯ เราจัดหาตามการประกอบต่อ เมื่อสร้างแอสเซมบลีทั้ง AssemblyInfo.cs และ CommonAssemblyInfo.cs จะถูกสร้างขึ้นในแต่ละแอสเซมบลี สิ่งนี้ทำให้เราได้สิ่งที่ดีที่สุดทั้งในโลกที่คุณอาจต้องการมีคุณสมบัติร่วมกันบางอย่างสำหรับทุกโครงการและค่านิยมเฉพาะสำหรับบางคน

หวังว่าจะช่วย


คุณมี 35+ รายการในการกำหนดค่าการสร้างเพื่อจัดการกับสิ่งนี้หรือไม่? ดูเหมือนจะค่อนข้างซ้ำซ้อน จะเกิดอะไรขึ้นถ้าคุณเพิ่มโครงการใหม่ 2 หรือ 3 โครงการจะไม่สร้างงานสร้างของคุณจนกว่าคุณจะเพิ่มงานโครงการหรือไม่
D3vtr0n

1
@ D3vtr0n ทำไม“ การกำหนดค่าการสร้าง” (คุณหมายถึงอะไร) ต้องการรายการจำนวนมาก ฉันคิดว่าไฟล์นี้รวมอยู่ใน. csproj แต่ละรายการผ่าน<Compile Include="$(MSBuildThisFileDirectory)..\Common\CommonAssemblyInfo.cs"/>คำสั่ง MSBuild ซึ่งอาจอยู่ในCommon.targetsไฟล์ที่แชร์ด้วย ใช้รหัส Yay
binki

15

โซลูชันที่นำเสนอโดย @JRoppert เกือบจะเหมือนกับสิ่งที่ฉันทำ ข้อแตกต่างเพียงอย่างเดียวคือฉันใส่บรรทัดต่อไปนี้ลงในไฟล์ AssemblyInfo.cs แบบโลคัลเนื่องจากสามารถแตกต่างกันในแต่ละชุดประกอบ:

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif
[assembly: AssemblyVersion("This is set by build process")]
[assembly: AssemblyFileVersion("This is set by build process")]
[assembly: CLSCompliant(true)]

ฉันยัง (โดยทั่วไป) ใช้ข้อมูลการชุมนุมทั่วไปหนึ่งรายการต่อโซลูชันโดยมีข้อสันนิษฐานว่าโซลูชันหนึ่งรายการเป็นสายผลิตภัณฑ์เดียว / ผลิตภัณฑ์ที่สามารถกู้คืนได้ ไฟล์ข้อมูลประกอบทั่วไปยังมี:

[assembly: AssemblyInformationalVersion("0.9.2.0")]

ซึ่งจะตั้งค่า "ProductVersion" ที่แสดงโดย Windows Explorer


8

ภารกิจชุมชน MSBuildมีงานที่กำหนดเองที่ชื่อว่า AssemblyInfo ซึ่งคุณสามารถใช้เพื่อสร้าง assemblyinfo.cs ของคุณ มันต้องการการแก้ไขไฟล์ csproj ของคุณด้วยมือเล็กน้อยเพื่อใช้ แต่คุ้มค่า


6

ในความคิดของฉันใช้ GlobalAssemblyInfo.cs มีปัญหามากกว่ามันคุ้มค่าเพราะคุณต้องแก้ไขทุกไฟล์โครงการและอย่าลืมแก้ไขทุกโครงการใหม่ในขณะที่คุณได้รับ AssemblyInfo.cs โดยค่าเริ่มต้น

สำหรับการเปลี่ยนแปลงค่าทั่วโลก (เช่น บริษัท ผลิตภัณฑ์ ฯลฯ ) การเปลี่ยนแปลงนั้นมักจะไม่บ่อยนักและง่ายต่อการจัดการฉันไม่คิดว่าDRYควรได้รับการพิจารณา เพียงเรียกใช้สคริปต์ MSBuild ต่อไปนี้ (ขึ้นอยู่กับMSBuild Extension Pack ) เมื่อคุณต้องการเปลี่ยนค่าในโครงการทั้งหมดด้วยตนเองแบบครั้งเดียว:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="UpdateAssemblyInfo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup>
        <AllAssemblyInfoFiles Include="..\**\AssemblyInfo.cs" />
    </ItemGroup>

    <Import Project="MSBuild.ExtensionPack.tasks" />

  <Target Name="UpdateAssemblyInfo">
    <Message Text="%(AllAssemblyInfoFiles.FullPath)" />
    <MSBuild.ExtensionPack.Framework.AssemblyInfo 
        AssemblyInfoFiles="@(AllAssemblyInfoFiles)"
        AssemblyCompany="Company"
        AssemblyProduct="Product"
        AssemblyCopyright="Copyright"
        ... etc ...
        />
  </Target>

</Project>

3

หากต้องการแชร์ไฟล์ระหว่างหลายโครงการคุณสามารถเพิ่มไฟล์ที่มีอยู่เป็นลิงค์

ในการทำเช่นนี้ให้เพิ่มไฟล์ที่มีอยู่แล้วคลิกที่ "เพิ่มเป็นลิงค์" ในตัวเลือกไฟล์ (ที่มา: free.fr )เพิ่มเป็นลิงค์

สำหรับสิ่งที่จะใส่ในไฟล์ที่ใช้ร่วมกันฉันขอแนะนำให้วางสิ่งต่าง ๆ ที่จะแชร์ข้ามแอสเซมบลี สิ่งต่าง ๆ เช่นลิขสิทธิ์ บริษัท รุ่นบางที


1

ไม่แนะนำให้ใช้ไฟล์ AseemblyInfo.cs เดียวสำหรับหลายโครงการ ไฟล์ AssemblyInfo มีข้อมูลที่อาจเกี่ยวข้องกับแอสเซมบลีเฉพาะนั้นเท่านั้น สองชิ้นที่เห็นได้ชัดที่สุดของข้อมูลเป็นและAssemblyTitleAssemblyVersion

ทางออกที่ดีกว่าอาจจะใช้targetsไฟล์ซึ่งจัดการโดย MSBuild เพื่อที่จะ "ฉีด" แอตทริบิวต์ประกอบกับโครงการมากกว่าหนึ่ง


ถ้าคุณมีมากกว่า 20 โครงการ ที่ต้องให้ฉันรักษา 20+ รายการในการกำหนดค่าการสร้างของฉันเพียงสำหรับการกำหนดรุ่น ดูเหมือนจะง่อยจริงๆ จะเกิดอะไรขึ้นถ้าฉันเพิ่มโครงการใหม่ 2 หรือ 3 โครงการ นั่นจะทำลายกระบวนการสร้าง ... ความคิดใด ๆ ที่จะแก้ปัญหานั้นได้อย่างไร
D3vtr0n

@ D3vtr0n ฉันคิดว่าความคิดคือการสร้างแอสเซมบลีที่เกี่ยวข้องแบบไดนามิกและไม่รักษาการกำหนดค่าส่วนบุคคลสำหรับแต่ละโครงการ ฉันคิดว่างานของชุมชนจัดการกรณีนี้
Roman

1

สิ่งหนึ่งที่ฉันพบว่ามีประโยชน์คือการสร้างองค์ประกอบ AssemblyVersion (ฯลฯ ) โดยใช้การทดแทนโทเค็นในขั้นตอนการสร้างล่วงหน้า

ผมใช้ TortoiseSVN และมันเป็นเรื่องง่ายที่จะใช้มันSubWCRev.exeเพื่อเปิดแม่แบบเข้าAssemblyInfo.wcrev AssemblyInfo.csบรรทัดที่เกี่ยวข้องในเทมเพลตอาจมีลักษณะดังนี้:

[assembly: AssemblyVersion("2.3.$WCREV$.$WCMODS?1:0$$WCUNVER?1:0$")]

องค์ประกอบที่สามคือหมายเลขการแก้ไข ฉันใช้องค์ประกอบที่สี่เพื่อตรวจสอบว่าฉันยังไม่ลืมที่จะส่งมอบไฟล์ใหม่หรือไฟล์ที่เปลี่ยนแปลงใด ๆ (องค์ประกอบที่สี่คือ 00 ถ้ามันใช้ได้ทั้งหมด)

โดยวิธีการเพิ่มAssemblyInfo.wcrevการควบคุมรุ่นของคุณและไม่สนใจ AssemblyInfo.csถ้าคุณใช้สิ่งนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.