Aracılığıyla paylaş


Projelere Göre Başvuruda Kullanılan Derlemeleri Seçin

Derlemeler, derleme sırasında iki farklı şekilde kullanılır. Birincisi derleme içindir; bu da paket tüketicisinin kodunun derlemedeki API'lere karşı derlemesini ve IntelliSense'in öneriler sunmasını sağlar. İkincisi, derlemenin dizine bin kopyalandığı ve program yürütmesi sırasında kullanıldığı çalışma zamanıdır. Bazı paket yazarları derleme zamanında yalnızca kendi derlemelerinin (veya derlemelerinin bir alt kümesinin) paket tüketicilerinin kullanımına sunulmasını ister, ancak çalışma zamanı için tüm bağımlılıklarını sağlaması gerekir. Bu belge, bu sonuca ulaşmanın yollarını arar.

Önerimiz, derleme başına bir pakete ve diğer derlemelere paket bağımlılıklarına sahip olmaktır. NuGet bir projeyi geri yüklediğinde varlık seçimi yapar ve özel farklı varlık sınıfları dahil, hariç ve özel varlık sınıfları oluşturmayı destekler. Paketinizin bağımlılıklarının paketinizi kullanan herkes için derleme zamanı varlıkları haline gelmesini önlemek için varlıkları özel hale compile getirebilirsiniz. Oluşturulan pakette bu, bağımlılığın dışında tutulmasına neden compile olur. Hiçbiri sağlanmadığında varsayılan özel varlıkların olduğunu contentfiles;build;analyzersunutmayın. Bu nedenle, veya ProjectReferenceiçinde PackageReference kullanmanız PrivateAssets="compile;contentfiles;build;analyzers" gerekir.

<ItemGroup>
  <ProjectReference Include="..\OtherProject\OtherProject.csproj" PrivateAssets="compile;contentfiles;build;analyzers" />
  <PackageReference Include="SomePackage" Version="1.2.3" PrivateAssets="compile;contentfiles;build;analyzers" />
</ItemGroup>

NuGet'in sizin için otomatik olarak oluşturmasına izin vermek yerine özel nuspec bir dosyadan paket oluşturuyorsanız XML nuspec özniteliğini exclude kullanmanız gerekir.

<dependencies>
  <group targetFramework=".NETFramework4.8">
    <dependency id="OtherProject" version="3.2.1" exclude="Compile,Build,Analyzers" />
    <dependency id="SomePackage" version="1.2.3" exclude="Compile,Build,Analyzers" />
  </group>
</dependencies>

Bunun önerilen çözüm olmasının üç nedeni vardır.

İlk olarak, yararlı derlemelere genellikle yeni derlemeler/paketler tarafından başvurulur. Bir yardımcı program derlemesinin bugün yalnızca tek bir paket tarafından kullanılması amaçlanmış olsa da, ikinci bir paket gelecekte "özel" yardımcı program derlemesini kullanmak isterse, yardımcı program derlemesinin yeni bir pakete taşınması ve eski paketin bunu bağımlılık olarak bildirecek şekilde güncelleştirilmesi gerekir. veya yardımcı program paketinin hem mevcut hem de yeni pakette göndermesi gerekir. Derleme iki farklı paketteyse ve bir proje her iki pakete de başvuruda bulunuyorsa, iki pakette yardımcı program derlemesinin farklı sürümleri varsa, NuGet sürüm yönetimine yardımcı olamaz.

İkincisi, paketinizi kullanan geliştiricilerin bağımlılıklarınızdaki API'leri de kullanmak istediği zamanlar olabilir. Örneğin, Microsoft.ServiceHub.Client sürüm 3.0.3078 paketini göz önünde bulundurun. Paketi indirir ve dosyayı denetlerseniz nuspec , bağımlılık olarak Microsoft.VisualStudio. başlayan iki paketi listelediğini görebilirsiniz; yani çalışma zamanında bunlara ihtiyacı vardır, ancak derleme varlıklarını da dışlar. Bu, Microsoft.ServiceHub.Client kullanan projelerin, bu paketleri açıkça yüklemediği sürece IntelliSense'te visual studio API'lerine sahip olmadığı veya projeyi oluşturacakları anlamına gelir. Ve bu, bir hariç tutma varlığına sahip bir paket bağımlılığının sahip olduğu avantajdır. Paketinizi kullanan projeler, bağımlılıklarınızı da kullanmak isterse API'leri kendileri için kullanılabilir hale getirmek için pakete bir başvuru ekleyebilir.

Son olarak, geçmişte bazı paket yazarlarının birden çok hedef çerçeveyi destekleyen paketler için NuGet'in derleme seçimi konusunda kafaları karışmıştı. Ana derlemeniz yardımcı program derlemeniz için farklı hedef çerçeveleri destekliyorsa, tüm derlemelerin hangi lib/ dizinlere yerleştirileceği belirgin olmayabilir. Her paketi derleme adına göre ayırarak, her derlemenin hangi lib/ klasörlere gitmesi gerektiği daha sezgiseldir. Bu, ve Package1.net6.0 paketlerine sahip olmak Package1.net48 anlamına gelmez. bu, içinde ve lib/net6.0/Package6.0Package1ve lib/netstandard2.0/Package2.dlllib/net5.0/Package2.dllPackage2içinde sahip olmak lib/net48/Package1.dll anlamına gelir. Nuget bir projeyi geri yüklediğinde, Nuget iki paket için bağımsız olarak varlık seçimi yapar.

Ayrıca bağımlılık ekleme/dışlama varlıklarının yalnızca PackageReference kullanan projeler tarafından kullanıldığını unutmayın. kullanarak paketinizi packages.config yükleyen tüm projelerde bağımlılıklarınız yüklenir ve API'leri de kullanılabilir. packages.config yalnızca Visual Studio'nun eski .NET Framework proje şablonları tarafından desteklenir. .NET Framework'leri hedefleyen sdk stili projeler bile öğesini desteklemez packages.configve bu nedenle bağımlılıkları dahil etme/dışlama bağımlılıklarını destekler.

PackageReference ve packages.config farklı özelliklere sahiptir. , packages.configveya her ikisini de kullanan PackageReferencepaket tüketicilerinizi desteklemek isteyip istemediğiniz, paketinizi yazma şeklinizi değiştirir.

NuGet'in MSBuild Pack hedefi, pakete proje başvurularını otomatik olarak dahil etme desteği sunmaz. Yalnızca bu başvuruda bulunan projeleri paket bağımlılıkları olarak listeler. GitHub'da, topluluk üyelerinin bu sonuca ulaşmanın yollarını paylaştığı bir sorun vardır. Bu sorun genellikle dosyaları pakete içerik ekleme belgelerinde açıklandığı gibi paketin herhangi bir yerine dosya yerleştirmek için MSBuild öğe meta verilerini kullanmayı ve proje başvurularının paket bağımlılıkları haline gelmesini önlemek için kullanmayı SuppressDependenciesWhenPacking içerirPackagePath. Bu özelliği destekleyen NuGet'in resmi paketine alternatif olarak kullanılabilecek topluluk tarafından geliştirilen araçlar da mevcuttur.

PackageReference Destek

Bir paket tüketicisi kullandığında PackageReference, NuGet daha önce açıklandığı gibi derleme ve çalışma zamanı varlıklarını bağımsız olarak seçer.

Derleme varlıkları tercih ref/<tfm>/*.dll eder (örneğin ref/net6.0/*.dll), ancak bu yoksa , (örneğinlib/net6.0/*.dll) öğesine lib/<tfm>/*.dll geri döner.

Çalışma zamanı varlıkları tercih runtimes/<rid>/lib/<tfm>/*.dll eder (örneğin (runtimes/win11-x64/lib/net6.0/*.dll)), ancak bu yoksa, öğesine geri lib/<tfm>/*.dlldöner.

içindeki ref\<tfm>\ derlemeler çalışma zamanında kullanılmadığından, paket boyutunu küçültmek için yalnızca meta veri derlemeleri olabilir.

packages.config Destek

NuGet paketlerini yönetmek için kullanan packages.config projeler normalde dizindeki lib\<tfm>\ tüm derlemelere başvurular ekler. ref\ Dizin, desteğine PackageReference eklendi ve bu nedenle kullanılırken packages.configdikkate alınmaz. kullanarak packages.configprojeler için hangi derlemelere başvurulacak açıkça ayarlamak için paketin <references> nuspec dosyasındaki öğesini kullanması gerekir. Örneğin:

<references>
    <group targetFramework="net45">
        <reference file="MyLibrary.dll" />
    </group>
</references>

MSBuild paketi hedefleri öğesini desteklemez <references> . MSBuild paketi kullanırken .nuspec dosyası kullanarak paketleme belgelerine bakın.

Not

packages.configproject, derlemeleri bin\<configuration>\ çıkış dizinine kopyalamak için ResolveAssemblyReference adlı bir işlem kullanır. Projenizin derlemesi kopyalanır, ardından derleme sistemi başvuruda bulunılan derlemeler için derleme bildirimine bakar, sonra bu derlemeleri kopyalar ve tüm derlemeler için yinelemeli olarak yinelenir. Bu, derlemelerden herhangi birinin yalnızca yansıma (Assembly.Load, MEF veya başka bir bağımlılık ekleme çerçevesi) tarafından yüklenmesi durumunda, içinde olmasına bin\<tfm>\rağmen projenizin bin\<configuration>\ çıkış dizinine kopyalanmayabileceği anlamına gelir. Bu aynı zamanda bunun P/Invoke ile çağrılan yerel kod için değil yalnızca .NET derlemeleri için çalıştığı anlamına gelir.

Hem hem de PackageReference desteği packages.config

Önemli

Bir paket nuspec <references> öğesini içeriyorsa ve içinde ref\<tfm>\derlemeler içermiyorsa NuGet, nuspec <references> öğesinde listelenen derlemeleri hem derleme hem de çalışma zamanı varlıkları olarak tanıtır. Bu, başvuruda bulunılan derlemelerin dizindeki başka bir derlemeyi lib\<tfm>\ yüklemesi gerektiğinde çalışma zamanı özel durumları olacağı anlamına gelir. Bu nedenle, destek için hem nuspec <references> kullanmak hem de destek için packages.configPackageReference klasördeki ref/ derlemeleri yinelemek önemlidir. runtimes/ Paket klasörünün kullanılması gerekmez, tamlık için yukarıdaki bölüme eklenmiştir.

Örnek

Paketim . MyLib.dllMyHelpers.dll NET Framework 4.7.2'yi hedefleyen , ve MyUtilities.dlladlı üç derlemeyi içerecek. MyUtilities.dll yalnızca diğer iki derleme tarafından kullanılması amaçlanan sınıfları içerdiğinden, bu sınıfları IntelliSense'te veya derleme zamanında paketimi kullanan projeler için kullanılabilir hale getirmek istemiyorum. Dosyamın nuspec aşağıdaki XML öğelerini içermesi gerekir:

<references>
    <group targetFramework="net472">
        <reference file="MyLib.dll" />
        <reference file="MyHelpers.dll" />
    </group>
</references>

Paket içeriğimin şunlar olduğundan emin olmak istiyorum:

lib\net472\MyLib.dll
lib\net472\MyHelpers.dll
lib\net472\MyUtilities.dll
ref\net472\MyLib.dll
ref\net472\MyHelpers.dll