.NET Core sınıf kitaplığını csproj ile nasıl birden çok hedeflersiniz?


96

.NET Core hala project.jsonbiçimi kullandığında, birden çok çerçeveyi hedefleyen bir sınıf kitaplığı oluşturabilirsiniz (örn. Net451, netcoreapp1.0).

Artık resmi proje biçimi csprojMSBuild kullandığına göre, hedeflenecek birden çok çerçeveyi nasıl belirlersiniz? Ben VS2017 proje ayarlarından bu aramaya çalışıyorum ama (hatta ben diğer tam .NET Framework sürümlerini listelemek olmayan tek .NET Çekirdek çerçeveler tek bir çerçeve hedef mümkün duyuyorum do kurduktan) :

görüntü açıklamasını buraya girin


Göründüğü gibi değil, açılır menüde listelenen .NETStandard 1.x seçeneklerini almanız gerekir. Bunun nasıl olduğu çok net değil, başlamak için doğru proje şablonunu seçtiğinizden emin olun. "Sınıf Kitaplığı (.NET Standard)" olmalıdır. Görünüşe göre Konsol Uygulaması şablonunu seçtiniz ve ardından özellikleri değiştirmeye başladınız, doğru yoldan değil. Aslında Sınıf Kitaplığı şablonunu kullandıysanız, kurulum iyi gitmedi.
Hans Passant

Aslında Sınıf Kitaplığı'nı (.NET Core) seçtim.
Gigi

2
Doğru, çoklu hedefleme yapmak istiyorsanız bu yanlıştır. Kitaplığı birden fazla platformda kullanılabilir hale getirmek için bir .NETStandard seçmelisiniz.
Hans Passant

Bu onu temizler. İsterseniz yorumlarınızdan bir cevap yazabilirsiniz.
Gigi

Yanıtlar:


122

Elle düzenlemeye proje dosyası ve eklenti ihtiyaç ler varsayılan için TargetFramework ve temelde olarak değiştirin TargetFrameworks . Sonra Moniker'dan a ; ayırıcı.

Ayrıca Nuget paketi referanslarını manuel olarak veya VS Nuget Paket Yöneticisini kullanarak koşullu bir ItemGroup'a yerleştirebilirsiniz.

.Csproj dosyanız şöyle görünmelidir:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.6;net452</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net452'">
    <PackageReference Include="Microsoft.Azure.DocumentDB">
      <Version>1.12.0</Version>
    </PackageReference>
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">
    <PackageReference Include="Microsoft.Azure.DocumentDB.Core">
    <Version>1.1.0</Version>
    </PackageReference>
  </ItemGroup>
</Project>

Bu günlerde eksik belgeler nedeniyle yaptığım başka bir geçici çözüm, VS2015'te bir proje oluşturmam ve mevcut belgeleri ve intellisense'i kullanarak project.json dosyasını oluşturmam, ardından çözümü VS2017'de açıp yerleşik yükseltmeyi kullanmam. Daha sonra bu yapılandırmanın nasıl gerçekleştirileceğini bulmak için csproj dosyasına bakacağım.

Moniker olmadan daha ezoterik hedefleri çoklu hedefleme :

Microsoft:

PCL'ler önerilmez +

PCL'ler desteklense de, paket yazarları bunun yerine netstandard'ı desteklemelidir. .

Bir Taşınabilir Profili hedeflemek isterseniz bir önceden tanımlanmış yok lakabı da olamaz anlaması Taşınabilir Profiller böylece TargetFrameworkIdentifier, TargetFrameworkVersionve TargetFrameworkProfile. Ayrıca bir derleyici sabiti otomatik olarak tanımlanmaz. Son olarak, tüm montaj referanslarını eklemeniz gerekir, hiçbiri varsayılan olarak sağlanmamıştır.

Aşağıdaki Örnek, dynamicanahtar kelimeyi kullanan bir projeden alınmıştır, bu nedenle ek olarak Microsoft.CSharpmontaja ihtiyaç duyar, böylece farklı hedefler için nasıl referans olduğunu görebilirsiniz.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.5;net40;portable40-net45+sl5+win8+wp8</TargetFrameworks>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8+wp8'">
    <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Profile158</TargetFrameworkProfile>
    <DefineConstants>$(DefineConstants);PORTABLE158</DefineConstants>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='netstandard1.5'">
    <PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
    <PackageReference Include="System.ComponentModel" Version="4.3.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='net40'">
    <Reference Include="Microsoft.CSharp" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8+wp8'">
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Windows" />
  </ItemGroup>
</Project>

1
Bunu csproj'u manuel olarak düzenleyerek mi yapmanız gerekiyor yoksa VS aracılığıyla yapılabilir mi?
Gigi

1
@Gigi çoklu hedeflemenin manuel olarak yapılması gerekiyor. Nuget paketleri VS2017 üzerinden veya manuel olarak yapılabilir.
Aboo

2
Aynı sorunu yaşıyordum ve URL'leri <TargetFramework> 'e ekledikten sonra her şey yolunda gitti. Keşke bu şeylerin daha iyi belgelenmesi.
Negorath

2
@AsadSaeeduddin şans, Resharper'ın size Visual Studio'yu değil dalgalı çizgileri göstermesidir. $ (TargetFramework) sadece bir ItemGroup'u belirli bir framework / Moniker için kullanılabilir kılmak için kullanılır.
Aboo

2
NuGet paketi doğru şekilde oluşturulmuşsa @ORMapper, içeri aktardığınızda otomatik olarak gerçekleşmelidir. NuGetPackageA zaten birden çok çerçeveyi destekliyorsa, bunu koşullu bir öğe grubuna koymanız gerekmez. Şimdi .net çerçevesi için PackageA'ya ve .net çekirdeği için PackageB'ye başvurmanız gerekirse, bunun koşullu öğe grubuna yerleştirilmesi gerekir. Bugün (Ekim 2017) itibariyle arayüzde herhangi bir seçenek bulunmamaktadır.
Aboo

24

Bunun .csprojiçin dosyayı manuel olarak düzenleyebilir ve özelliğini TargetFrameworks(değil TargetFramework) ayarlayabilirsiniz .

<TargetFrameworks>net451;netstandard1.4</TargetFrameworks>

Örneğin bkz . EFCore.csproj: https://github.com/aspnet/EntityFrameworkCore/blob/951e4826a38ad5499b9b3ec6645e47c825fa842a/src/EFCore/EFCore.csproj


9
Teşekkürler! Beni öldürüyor. Brian Kernigan'ın kırk yıl önce yazdığı "Programlama Stilinin Unsurları" nda, sonunda tek bir harfle farklılık gösteren değişkenleri kullanmanın hatalarından bahsediyor. Ad "TargetFrameworkList" olsaydı çok daha net olurdu.
howardlo

Gösterdiğiniz örnek bir <TargetFrameworks> özelliği içermiyor.
RenniePet

@RenniePet, teşekkürler! Proje dosyası zamanla değişti. Bağlantıyı, <TargetFrameworks> olan somut bir kesinleştirme ile değiştirdim.
Gece yürüyüşçüsü

12

Aslında Sınıf Kitaplığı'nı (.NET Core) seçtim.

Kitaplığınızın birden çok platform hedefi üzerinde çalışması gerekiyorsa, istediğiniz proje şablonu bu değildir. Bu proje şablonuyla, kitaplığınız yalnızca .NETCore'u hedefleyen bir projede kullanılabilir. PCL kitaplığı yaklaşımı kaldırıldı, şimdi bir .NETStandard seçmeniz gerekiyor.

Bunu, projeyi "Sınıf Kitaplığı (.NET Standard)" proje şablonuyla başlatarak yaparsınız. Artık .NETStandard sürümünü seçme seçeneğiniz var. Mevcut uyumluluk ızgarası burada .

Umarım bağlantılı makaleyi güncel tutacaklardır. Bu akış halindedir, .NETStandard 2.0 çakılmıştır ancak henüz gönderilmemiştir. 2017 yılının 2. çeyreği için hedeflenen, muhtemelen baharın sonu, şu anda% 97 tamamlandı olarak gösteriyor. Tasarımcıların 1.5 veya 1.6 kullanmanın tavsiye edilmediğini, 2.0 ile yeterince uyumlu olmadığını söylediklerine kulak misafiri oldum.


Farklı hedef çerçeveler için farklı bağımlılıklarınız varsa nasıl çalışır? Demek istediğim, project.jsonbir hedef çerçeve için belirli bağımlılıkları belirtebilirsiniz.
Gigi

1
Bunun var olduğunu unutmanız gerektiğine% 90 eminim. Bu, .NETCore'u önyüklemek için sadece geçici bir önlem olan kafa karıştırıcı bir karışıklıktı. Bağlandığım uyumluluk ızgarasını kullanın.
Hans Passant

Ben de şüphelendim. Açıkladığınız için çok teşekkürler!
Gigi

4
@HansPassant çoklu hedef, eski kodunuz varsa hala en iyi seçenektir ve aynı zamanda yeşil alan geliştirmeniz en son tam çerçeve çeşnilerinden veya dotnetcore'larından birinde yapılabilir.
Stefano Ricciardi

1
Yeşil alan bile henüz .NET Core dostu değildir. Azure Function Apps kullanıyorum ancak .NET Core sürümleri yalnızca birkaç tetikleyiciyi destekliyor. (Service Bus tetikleyicilere ihtiyacım var, bu yüzden .NET Framework ile sıkışıp kaldım ve çok büyük bir iş işlevselliği kitaplığı çoklu hedef olarak ortaya çıkabilir.) Microsoft'un platformu şu anda karışık bir karmaşa. DLL Hell'in modern eşdeğeridir.
McGuireV10

5

Basit 1 satırlık düzeltmeyle başlayan ve ardından her bir komplikasyonda size yol gösteren çoklu hedefleme ağ çerçevesi ve netcore için yeni başlayanlar için bir kılavuz hazırladım .

En basit yaklaşım, ilk önce çalışan bir netcore veya netstandard hedefi elde etmektir. Sonra csproj dosyasını düzenleyin ve diğer hedefler için bu adımları uygulayın.

  1. Her hedef için farklı bağımlılıklar tanımlayabilmek için csproj dosyanızdaki koşullu bölümler hakkında bilgi edinin. Her hedef için koşullu bölümler oluşturun.
  2. Ekle <Reference />sSistemi için. * Herhangi netframework hedefler için DLL dosyaları sadece mesajları demek Yapı hatasının ne eksik okuyarak.
  3. <PackageReference />sHer hedef için aynı olmadıkları durumlarda NuGet bağımlılıklarıyla ilgilenin . En kolay numara, GUI'nin Nuget referanslarını sizin için doğru bir şekilde işleyebilmesi için geçici olarak tek hedeflemeye geri dönmektir.
  4. Yaratıcı çeşitli teknikler, geçici çözümler ve zaman kazandırıcıları öğrenerek tüm hedeflerde derlenmeyen kodla başa çıkın.
  5. Daha fazla hedef eklemenin maliyeti çok yüksek olduğunda kayıplarınızı ne zaman azaltacağınızı bilin.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.