Güzel bir sorunuz var. Muhtemelen çözümünüzle bazı değiş tokuşlar vardır. Nihai cevap gerçekten platforma bağlı ne demek istediğinize bağlıdır. Örneğin, harici uygulamaları başlatmak için bir işlem başlatıyorsanız ve sadece bir uygulama ile diğeri arasında geçiş yapıyorsanız, bunu çok fazla karmaşıklık olmadan halledebilirsiniz. P / Invoke ile yerel kütüphaneler hakkında konuşuyorsanız, yapılması gereken biraz daha var. Ancak, yalnızca bir platformda bulunan kitaplıklarla bağlantı kuruyorsanız, büyük olasılıkla birden fazla derleme kullanmanız gerekecektir.
Harici uygulamalar
Muhtemelen #if
bu durumda ifadeler kullanmanıza gerek yoktur . Sadece bazı arayüzler kurun ve platform başına bir uygulamaya sahip olun. Platformu algılamak ve doğru örneği sağlamak için bir fabrika kullanın.
Bazı durumlarda, yalnızca belirli bir platform için derlenmiş bir ikili dosyadır, ancak çalıştırılabilir dosyanın adı ve tüm parametreler aynı şekilde tanımlanır. Bu durumda, doğru çalıştırılabilir dosyayı çözme meselesi. Windows ve Linux'ta çalışabilen bir toplu ses dönüştürücü uygulaması için, ikili adı çözmek için statik bir başlatıcı vardı.
public class AudioProcessor
{
private static readonly string AppName = "lame";
private static readonly string FullAppPath;
static AudioProcessor()
{
var platform = DetectPlatform();
var architecture = Detect64or32Bits();
FullAppPath = Path.combine(platform, architecture, AppName);
}
}
Burada süslü bir şey yok. Sadece iyi ol moda sınıfları.
P / çağırır
P / Invoke biraz daha hileli. Sonuç olarak, yerel kütüphanenin doğru sürümünün yüklendiğinden emin olmanız gerekir. Pencerelerde P / Invoke olur SetDllDirectory()
. Farklı platformların bu adıma ihtiyacı olmayabilir. İşte işler burada dağınık olabilir. #if
Özellikle dağıtım paketinize ekliyorsanız, kütüphane yolunuzun çözümlenmesini denetlemek için hangi çağrının kullanılacağını kontrol etmek için ifadeler kullanmanız gerekebilir .
Tamamen farklı platforma bağımlı kütüphanelere bağlanma
Eski okul çoklu hedefleme yaklaşımı burada yararlı olabilir. Ancak çok çirkinlik ile geliyor. Bazı projelerin aynı DLL hedef Silverlight, WPF ve potansiyel olarak UAP'yi kullanmaya çalıştığı günlerde, uygulamayı farklı derleme etiketleriyle birden çok kez derlemeniz gerekir. Yukarıdaki platformların her biriyle ilgili zorluk, aynı kavramları paylaşırken, platformların bu farklılıklar üzerinde çalışmanızdan yeterince farklı olmasıdır. Burası cehenneme giriyoruz #if
.
Bu yaklaşım, .csproj
platforma bağımlı referansları işlemek için dosyayı elle düzenlemeyi de gerektirir . Senin bu yana .csproj
dosya bir MSBuild dosyasıdır, bilinen bir ve öngörülebilir bir şekilde yapmak tamamen mümkün.
# cehennem
Kodlar bölümlerini #if
deyimler kullanarak açıp kapatabilirsiniz, böylece uygulamalar arasındaki küçük farkların ele alınmasında etkili olur. Yüzeyde iyi bir fikir gibi geliyor. Hatta çizim kodunda hata ayıklamak için sınırlayıcı kutu görselleştirmeyi açmak ve kapatmak için bir araç olarak kullandım.
İle 1 numaralı sorun #if
olduğunu hiçbiri ayrıştırıcı tarafından değerlendirilir kapatılır kod. Gizli sözdizimi hataları veya daha da kötüsü, kitaplığı yeniden derlemenizi bekleyen mantık hataları olabilir. Bu, yeniden düzenleme koduyla daha da sorunlu hale gelir. Bir yöntemi yeniden adlandırmak veya parametrelerin sırasını değiştirmek kadar basit bir şey normal olarak ele alınacaktır, ancak ayrıştırıcı #if
ifadeyle kapatılan hiçbir şeyi değerlendirmediği için, aniden yeniden derleyene kadar göremeyeceğiniz bozuk bir kodunuz vardır.
Bu şekilde yazılmış tüm hata ayıklama kodum, bir dizi yeniden düzenleme işlemi kırıldıktan sonra yeniden yazılmak zorunda kaldı. Yeniden yazma sırasında, bu özellikleri açmak ve kapatmak için genel bir yapılandırma sınıfı kullandım. Bu, aracı yeniden kanıtladı, ancak böyle bir çözüm, API tamamen farklı olduğunda yardımcı olmaz.
Tercih ettiğim yöntem
Öğrenilen birçok acı verici derse ve hatta Microsoft'un kendi örneğine dayalı olarak tercih ettiğim yöntem, birden fazla derleme kullanmaktır.
Bir çekirdek NetStandard derlemesi tüm arabirimleri tanımlar ve tüm ortak kodu içerir. Platforma bağlı uygulamalar, dahil edildiğinde özellikler ekleyecek ayrı bir montajda olacaktır.
Bu yaklaşım, yeni Yapılandırma API'sı ve mevcut Kimlik mimarisi ile örneklenmiştir. Daha spesifik entegrasyonlara ihtiyacınız olduğu için, bu yeni montajları eklemeniz yeterlidir. Bu montajlar ayrıca kendi kurulumunuza dahil etmek için uzatma işlevleri sağlar. Bir bağımlılık enjeksiyon yaklaşımı kullanıyorsanız, bu genişletme yöntemleri kitaplığın hizmetlerini kaydetmesine izin verir.
Bu, #if
cehennemden kaçınmanın ve oldukça farklı bir ortamı tatmin etmenin tek yolu hakkında .