Aracılığıyla paylaş


Yönetilen Genişletilebilirlik Çerçevesi (MEF)

Bu makalede, .NET Framework 4'te kullanıma sunulan Yönetilen Genişletilebilirlik Çerçevesi'ne genel bir bakış sağlanır.

MEF nedir?

Yönetilen Genişletilebilirlik Çerçevesi (MEF), basit ve genişletilebilir uygulamalar oluşturmaya yönelik bir kitaplıktır. Uygulama geliştiricilerinin yapılandırma gerektirmeden uzantıları bulmasına ve kullanmasına olanak tanır. Ayrıca uzantı geliştiricilerinin kodu kolayca kapsüllemesi ve hassas zor bağımlılıklardan kaçınmasına olanak tanır. MEF yalnızca uzantıların uygulamalar içinde değil, uygulamalar arasında da yeniden kullanılmasına izin verir.

Genişletilebilirlik sorunu

Genişletilebilirlik desteği sağlaması gereken büyük bir uygulamanın mimarı olduğunuzu düşünün. Uygulamanızın büyük olasılıkla çok sayıda daha küçük bileşen içermesi gerekir ve bunları oluşturup çalıştırmak sizin sorumluluğunuzdadır.

Soruna yönelik en basit yaklaşım, bileşenleri uygulamanıza kaynak kod olarak eklemek ve bunları doğrudan kodunuzdan çağırmaktır. Bunun bir dizi belirgin dezavantajı vardır. En önemlisi, örneğin bir Web uygulamasında kabul edilebilir ancak istemci uygulamasında çalışılamayan bir kısıtlama olan kaynak kodu değiştirmeden yeni bileşenler ekleyemezsiniz. Aynı derecede sorunlu olan bileşenler için kaynak koduna erişiminiz olmayabilir, çünkü bunlar üçüncü taraflarca geliştirilebilir ve aynı nedenle sizinkine erişmelerine izin veremezsiniz.

Uygulama ve bileşenleri arasında ayrıştırmaya izin vermek için bir uzantı noktası veya arabirim sağlamak biraz daha karmaşık bir yaklaşım olabilir. Bu model altında, bir bileşenin uygulayabileceği bir arabirim ve uygulamanızla etkileşim kurmasını sağlamak için bir API sağlayabilirsiniz. Bu, kaynak kodu erişimi gerektirme sorununu çözer, ancak yine de kendi güçlüklerine sahiptir.

Uygulama kendi başına bileşenleri bulmak için herhangi bir kapasiteye sahip olmadığından, yine de hangi bileşenlerin kullanılabilir olduğu ve yüklenmesi gerektiği açıkça bildirilmelidir. Bu genellikle kullanılabilir bileşenleri bir yapılandırma dosyasına açıkça kaydederek gerçekleştirilir. Bu, bileşenlerin doğru olduğundan emin olmanın, özellikle de güncellemeyi yapmakla geliştiricinin değil, son kullanıcının yükümlü olduğu durumlarda bakım sorununa dönüşmesi anlamına gelir.

Buna ek olarak, bileşenler uygulamanın kendisinin katı olarak tanımlanmış kanalları dışında birbirleriyle iletişim kuramaz. Uygulama mimarı belirli bir iletişim gereksinimini tahmin etmediyse, bu genellikle imkansızdır.

Son olarak, bileşen geliştiricilerinin hangi derlemenin uyguladıkları arabirimi içerdiğine yönelik sabit bir bağımlılığı kabul etmesi gerekir. Bu, bir bileşenin birden fazla uygulamada kullanılmasını zorlaştırır ve bileşenler için bir test çerçevesi oluşturduğunuzda da sorun oluşturabilir.

MEF'nin sağladığı bilgiler

MEF, kullanılabilir bileşenlerin bu açık kaydı yerine, oluşturma yoluyla bunları örtük olarak keşfetmenin bir yolunu sağlar. Parça olarak adlandırılan MEF bileşeni, hem bağımlılıklarını (içeri aktarmalar olarak bilinir) hem de hangi özellikleri (dışarı aktarmalar olarak bilinir) kullanılabilir hale getirdiğini bildirimli olarak belirtir. Bir parça oluşturulduğunda, MEF oluşturma altyapısı içeri aktarmalarını diğer parçalardan sağlananlarla karşılar.

Bu yaklaşım, önceki bölümde açıklanan sorunları çözer. MEF bölümleri özelliklerini bildirimli olarak belirttiğinden, çalışma zamanında bulunabilirler, bu da bir uygulamanın sabit kodlanmış başvurular veya kırılgan yapılandırma dosyaları olmadan bölümleri kullanabileceği anlamına gelir. MEF, uygulamaların parçaların örneğini oluşturmadan ve hatta derlemelerini yüklemeden meta verilerine göre parçaları bulmasına ve incelemesine olanak tanır. Sonuç olarak, uzantıların ne zaman ve nasıl yükleneceğini dikkatli bir şekilde belirtmeniz gerekmez.

Sağlanan dışarı aktarmalarına ek olarak, bir parça içeri aktarmalarını belirtebilir ve bu da diğer parçalar tarafından doldurulacaktır. Bu, parçalar arasındaki iletişimi sadece mümkün kılmakla kalmaz, aynı zamanda kolay hale getirir ve kodun iyi bir şekilde parçalanmasını sağlar. Örneğin, birçok bileşenle ortak olan hizmetler ayrı bir bölüme ayrılabilir ve kolayca değiştirilebilir veya yerine konulabilir.

MEF modeli belirli bir uygulama derlemesine sabit bağımlılık gerektirmediğinden, uzantıların uygulamadan uygulamaya yeniden kullanılmasına olanak tanır. Bu, uzantı bileşenlerini test etmek için uygulamadan bağımsız bir test koşumu geliştirmeyi de kolaylaştırır.

MEF kullanılarak yazılan genişletilebilir bir uygulama, uzantı bileşenleri tarafından doldurulabilen bir içeri aktarma bildirir ve uygulama hizmetlerini uzantılara sunmak için dışarı aktarmaları da bildirebilir. Her uzantı bileşeni bir dışarı aktarma bildirir ve içeri aktarmaları da bildirebilir. Bu şekilde uzantı bileşenlerinin kendileri otomatik olarak genişletilebilir.

MEF'nin kullanılabildiği yerler

MEF, .NET Framework 4'ün ayrılmaz bir parçasıdır ve .NET Framework'ün kullanıldığı her yerde kullanılabilir. Windows Forms, WPF veya başka bir teknoloji kullanan istemci uygulamalarınızda ya da ASP.NET kullanan sunucu uygulamalarında MEF kullanabilirsiniz.

MEF ve MAF

.NET Framework'ün önceki sürümleri, uygulamaların uzantıları yalıtmasına ve yönetmesine izin vermek için tasarlanmış Yönetilen Eklenti Çerçevesi'ni (MAF) kullanıma sunmşu. MAF'nin odak noktası MEF'den biraz daha yüksek seviyededir ve uzantı yalıtımı ile montaj yükleme ve boşaltılmasına odaklanırken, MEF'nin odak noktası bulunabilirlik, genişletilebilirlik ve taşınabilirliktir. İki çerçeve sorunsuz bir şekilde birlikte çalışabilir ve tek bir uygulama her iki durumdan da yararlanabilir.

SimpleCalculator: Örnek bir uygulama

MEF'in neler yapabileceğini görmenin en basit yolu, basit bir MEF uygulaması oluşturmaktır. Bu örnekte SimpleCalculator adlı çok basit bir hesap makinesi oluşturacaksınız. SimpleCalculator'ın amacı, "5+3" veya "6-2" biçiminde temel aritmetik komutları kabul eden ve doğru yanıtları döndüren bir konsol uygulaması oluşturmaktır. MEF kullanarak, uygulama kodunu değiştirmeden yeni işleçler ekleyebilirsiniz.

Bu örneğin tam kodunu indirmek için simpleCalculator örneğine (Visual Basic) bakın.

Uyarı

SimpleCalculator'ın amacı, kullanımı için gerçekçi bir senaryo sağlamak yerine MEF kavramlarını ve söz dizimini göstermektir. MEF'in gücünden en çok yararlanabilecek uygulamaların çoğu SimpleCalculator'dan daha karmaşıktır. Daha kapsamlı örnekler için GitHub'da Yönetilen Genişletilebilirlik Çerçevesi'ne bakın.

  • Başlamak için Visual Studio'da yeni bir Konsol Uygulaması projesi oluşturun ve adını verin SimpleCalculator.

  • MEF'nin yer aldığı System.ComponentModel.Composition derlemeye bir başvuru ekleyin.

  • Module1.vb veya Program.cs dosyasını açın ve Imports ile using için System.ComponentModel.Composition veya System.ComponentModel.Composition.Hosting yönergeleri ekleyin. Bu iki ad alanı, genişletilebilir bir uygulama geliştirmek için ihtiyacınız olacak MEF türlerini içerir.

  • Visual Basic kullanıyorsanız, Public modülünü bildiren satıra Module1 anahtar sözcüğünü ekleyin.

Kompozisyon konteyneri ve kataloglar

MEF kompozisyon modelinin çekirdeği, kullanılabilir tüm parçaları içeren ve kompozisyonu gerçekleştiren kompozisyon kapsayıcısıdır. Bileşim, ithalatın ihracatla eşleştirilmesidir. En yaygın oluşturma kapsayıcısı CompositionContainertürüdür ve bunu SimpleCalculator için kullanacaksınız.

Visual Basic kullanıyorsanız Program adlı bir genel sınıf ekleyin.

Module1.vb ProgramProgram.cs sınıfına aşağıdaki satırı ekleyin:

Dim _container As CompositionContainer
private CompositionContainer _container;

Bunun için kullanılabilir parçaları keşfetmek için, oluşturma kapsayıcıları bir katalog kullanır. Katalog, bazı kaynaklardan bulunan kullanılabilir bölümleri sağlayan bir nesnedir. MEF, sağlanan bir tür, derleme veya dizinden bölümleri bulmak için kataloglar sağlar. Uygulama geliştiricileri, Web hizmeti gibi diğer kaynaklardan parçaları bulmak için kolayca yeni kataloglar oluşturabilir.

Sınıfına aşağıdaki oluşturucuyu Program ekleyin:

Public Sub New()
    ' An aggregate catalog that combines multiple catalogs.
     Dim catalog = New AggregateCatalog()

    ' Adds all the parts found in the same assembly as the Program class.
    catalog.Catalogs.Add(New AssemblyCatalog(GetType(Program).Assembly))

    ' Create the CompositionContainer with the parts in the catalog.
    _container = New CompositionContainer(catalog)

    ' Fill the imports of this object.
    Try
        _container.ComposeParts(Me)
    Catch ex As CompositionException
        Console.WriteLine(ex.ToString)
    End Try
End Sub
private Program()
{
    try
    {
        // An aggregate catalog that combines multiple catalogs.
        var catalog = new AggregateCatalog();
        // Adds all the parts found in the same assembly as the Program class.
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));

        // Create the CompositionContainer with the parts in the catalog.
        _container = new CompositionContainer(catalog);
        _container.ComposeParts(this);
    }
    catch (CompositionException compositionException)
    {
        Console.WriteLine(compositionException.ToString());
    }
}

ComposeParts çağrısı, oluşturma kapsayıcısına belirli bir parça kümesini oluşturmasını bildirir; bu durumda, geçerli örneği Program. Bu noktada, ancak hiçbir şey olmaz çünkü doldurulacak içeri aktarma yok Program.

Özniteliklerle İçeri ve Dışarı Aktarmalar

İlk olarak, bir hesap makinesi içeri aktaracaksınız Program . Bu, Program içindeki konsol girişi ve çıkışı gibi kullanıcı arabirimi ile ilgili unsurların hesaplayıcı mantığından ayrılabilmesini sağlar.

Program sınıfına aşağıdaki kodu ekleyin:

<Import(GetType(ICalculator))>
Public Property calculator As ICalculator
[Import(typeof(ICalculator))]
public ICalculator calculator;

Nesnenin bildiriminin calculator olağan dışı olmadığını, ancak ImportAttribute özniteliğiyle donatıldığını fark edin. Bu öznitelik bir şeyi içeri aktarma olarak bildirir; yani, nesne oluşturulduğunda oluşturma altyapısı tarafından doldurulur.

Her içeri aktarmanın hangi dışarı aktarmalarla eşleşeceğini belirleyen bir sözleşmesi vardır. Sözleşme açıkça belirtilen bir dize olabileceği gibi, MEF tarafından belirli bir türden, bu durumda arayüz ICalculator, otomatik olarak oluşturulabilir. Eşleşen bir sözleşmeyle bildirilen tüm dışarı aktarmalar bu ithalatı yerine getirecektir. Nesnenin calculator türü aslında ICalculatorolsa da, bunun gerekli olmadığını unutmayın. Sözleşme, içeri aktarılan nesnenin türünden bağımsızdır. (Bu durumda, typeof(ICalculator) öğesini dışarıda bırakabilirsiniz. MEF, siz açıkça belirtmediğiniz sürece, sözleşmenin içeri aktarma türüne dayalı olarak kabul edileceğini varsayar.)

Bu çok basit arabirimi modüle veya SimpleCalculator ad alanına ekleyin:

Public Interface ICalculator
    Function Calculate(input As String) As String
End Interface
public interface ICalculator
{
    string Calculate(string input);
}

tanımladığınıza ICalculatorgöre, bunu uygulayan bir sınıfa ihtiyacınız vardır. Modüle veya SimpleCalculator ad alanına aşağıdaki sınıfı ekleyin:

<Export(GetType(ICalculator))>
Public Class MySimpleCalculator
   Implements ICalculator

End Class
[Export(typeof(ICalculator))]
class MySimpleCalculator : ICalculator
{

}

Bu, Program içindeki içeri aktarmayla eşleşecek dışarı aktarma. Dışarı aktarmanın içeri aktarmayla eşleşmesi için dışarı aktarmanın aynı sözleşmeye sahip olması gerekir. Dayalı olarak typeof(MySimpleCalculator) bir sözleşmeyle ihracat yapmak uyuşmazlığa neden olur ve ithalat tamamlanmaz; sözleşmenin tam olarak eşleşmesi gerekir.

Kompozisyon kapsayıcısı, bu montajda mevcut olan tüm parçalar ile doldurulacağı için MySimpleCalculator parçası da kullanılabilir olacaktır. Bir Program oluşturucu, Program nesne üzerinde bileşen oluşturduğunda, içeri aktarma, bu amaçla oluşturulacak bir MySimpleCalculator nesneyle doldurulacaktır.

Kullanıcı arabirimi katmanının (Program) başka bir şey bilmesi gerekmez. Bu nedenle, Main yöntemindeki kullanıcı arabirimi mantığının geri kalanını doldurabilirsiniz.

Main yöntemine aşağıdaki kodu ekleyin:

Sub Main()
    ' Composition is performed in the constructor.
    Dim p As New Program()
    Dim s As String
    Console.WriteLine("Enter Command:")
    While (True)
        s = Console.ReadLine()
        Console.WriteLine(p.calculator.Calculate(s))
    End While
End Sub
static void Main(string[] args)
{
    // Composition is performed in the constructor.
    var p = new Program();
    Console.WriteLine("Enter Command:");
    while (true)
    {
        string s = Console.ReadLine();
        Console.WriteLine(p.calculator.Calculate(s));
    }
}

Bu kod, yalnızca bir giriş satırını okur ve sonucu, Calculate işlevine geçirerek elde edilen sonucu konsola geri yazar. içinde ihtiyacınız olan tüm kod bu kadardır Program. İşin geri kalanı parçalarda gerçekleşecek.

Imports ve ImportMany öznitelikleri

SimpleCalculator'ın genişletilebilir olması için bir işlem listesini içeri aktarması gerekir. Sıradan ImportAttribute bir öznitelik, bir ve yalnızca bir ExportAttributeile doldurulur. Birden fazla kullanılabilir durumdaysa, birleştirme motoru hata verir. Herhangi bir sayıda dışa aktarım tarafından doldurulabilecek bir içeri aktarma oluşturmak için ImportManyAttribute özniteliğini kullanabilirsiniz.

MySimpleCalculator sınıfına aşağıdaki operations özelliğini ekleyin.

<ImportMany()>
Public Property operations As IEnumerable(Of Lazy(Of IOperation, IOperationData))
[ImportMany]
IEnumerable<Lazy<IOperation, IOperationData>> operations;

Lazy<T,TMetadata> , MEF tarafından aracılı olarak çıkışları tutmak için sağlanan bir türdür. Burada, dışarı aktarılan nesnenin kendisine ek olarak, dışarı aktarma meta verilerini veya dışarı aktarılan nesneyi açıklayan bilgileri de alırsınız. Her Lazy<T,TMetadata> birinde gerçek bir işlemi temsil eden bir IOperation nesne ve meta verilerini temsil eden bir IOperationData nesne bulunur.

Modüle veya SimpleCalculator ad alanına aşağıdaki basit arabirimleri ekleyin:

Public Interface IOperation
    Function Operate(left As Integer, right As Integer) As Integer
End Interface

Public Interface IOperationData
    ReadOnly Property Symbol As Char
End Interface
public interface IOperation
{
     int Operate(int left, int right);
}

public interface IOperationData
{
    char Symbol { get; }
}

Bu durumda, her işlemin meta verileri +, -, * gibi işlemi temsil eden simgedir. Ekleme işlemini kullanılabilir hale getirmek için modüle veya SimpleCalculator ad alanına aşağıdaki sınıfı ekleyin:

<Export(GetType(IOperation))>
<ExportMetadata("Symbol", "+"c)>
Public Class Add
    Implements IOperation

    Public Function Operate(left As Integer, right As Integer) As Integer Implements IOperation.Operate
        Return left + right
    End Function
End Class
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '+')]
class Add: IOperation
{
    public int Operate(int left, int right)
    {
        return left + right;
    }
}

ExportAttribute özniteliği daha önce olduğu gibi çalışır. ExportMetadataAttribute özniteliği, bu dışarı aktarma işlemine ad-değer çifti biçiminde meta veriler ekler. Add sınıfı IOperation'i uygularken, IOperationData'yi uygulayan bir sınıf açıkça tanımlı değildir. Bunun yerine, MEF tarafından sağlanan meta verilerin adlarına dayalı olarak üstü kapalı bir şekilde bir sınıf oluşturulur. (Bu, MEF'de meta verilere erişmenin çeşitli yollarından biridir.)

MEF'de kompozisyon özyinelemelidir. Program nesnesini açıkça oluşturdunuz, türünde olduğu ortaya çıkan ICalculator bir MySimpleCalculator öğesini içe aktardı. MySimpleCalculator, bir IOperation nesne koleksiyonunu içeri aktarır ve bu içeri aktarma, MySimpleCalculator oluşturulduğunda, tıpkı Program içeri aktarmaları gibi aynı zamanda doldurulacaktır. Eğer Add sınıfı başka bir içeri aktarma deklare edildiyse, o da doldurulmalıdır ve benzeri. Tamamlanmamış her içe aktarma, bir oluşturma hatasıyla sonuçlanır. (Ancak, içeri aktarmaları isteğe bağlı olarak bildirmek veya bunlara varsayılan değerler atamak mümkündür.)

Hesap makinesi mantığı

Bu parçalar yerine yerleştirildiğinde kalan tek şey hesap makinesi mantığının kendisidir. yöntemini uygulamak için sınıfına MySimpleCalculatorCalculate aşağıdaki kodu ekleyin:

Public Function Calculate(input As String) As String Implements ICalculator.Calculate
    Dim left, right As Integer
    Dim operation As Char
    ' Finds the operator.
    Dim fn = FindFirstNonDigit(input)
    If fn < 0 Then
        Return "Could not parse command."
    End If
    operation = input(fn)
    Try
        ' Separate out the operands.
        left = Integer.Parse(input.Substring(0, fn))
        right = Integer.Parse(input.Substring(fn + 1))
    Catch ex As Exception
        Return "Could not parse command."
    End Try
    For Each i As Lazy(Of IOperation, IOperationData) In operations
        If i.Metadata.symbol = operation Then
            Return i.Value.Operate(left, right).ToString()
        End If
    Next
    Return "Operation not found!"
End Function
public String Calculate(string input)
{
    int left;
    int right;
    char operation;
    // Finds the operator.
    int fn = FindFirstNonDigit(input);
    if (fn < 0) return "Could not parse command.";

    try
    {
        // Separate out the operands.
        left = int.Parse(input.Substring(0, fn));
        right = int.Parse(input.Substring(fn + 1));
    }
    catch
    {
        return "Could not parse command.";
    }

    operation = input[fn];

    foreach (Lazy<IOperation, IOperationData> i in operations)
    {
        if (i.Metadata.Symbol.Equals(operation))
        {
            return i.Value.Operate(left, right).ToString();
        }
    }
    return "Operation Not Found!";
}

İlk adımlar giriş dizesini sol ve sağ işlenenlere ve bir işleç karakterine ayrıştırıyor. Döngüde foreach , koleksiyonun operations her üyesi inceleniyor. Bu nesneler Lazy<T,TMetadata> türündedir ve meta veri değerlerine Metadata özelliğiyle, dışarı aktarılan nesnelere ise Value özelliğiyle erişilebilir. Bu durumda, Symbol nesnesinin IOperationData özelliği bir eşleşme olarak bulunursa, hesap makinesi Operate nesnesinin IOperation yöntemini çağırır ve sonucu döndürür.

Hesaplayıcıyı tamamlamak için, bir dizedeki ilk basamak olmayan karakterin konumunu döndüren bir yardımcı yöntemine de ihtiyacınız vardır. Sınıfına aşağıdaki yardımcı yöntemi MySimpleCalculator ekleyin:

Private Function FindFirstNonDigit(s As String) As Integer
    For i = 0 To s.Length - 1
        If Not Char.IsDigit(s(i)) Then Return i
    Next
    Return -1
End Function
private int FindFirstNonDigit(string s)
{
    for (int i = 0; i < s.Length; i++)
    {
        if (!char.IsDigit(s[i])) return i;
    }
    return -1;
}

Artık projeyi derleyip çalıştırabiliyor olmanız gerekir. Visual Basic'te Public anahtar sözcüğünü Module1 öğesine eklediğinizden emin olun. Konsol penceresine "5+3" gibi bir ekleme işlemi yazın ve hesap makinesi sonuçları döndürür. Herhangi bir diğer işleç "İşlem Bulunamadı!" iletisiyle sonuçlanıyor.

SimpleCalculator'ı yeni bir sınıf kullanarak genişletme

Hesap makinesi artık çalıştığına göre, yeni bir işlem eklemek kolaydır. Modüle veya SimpleCalculator ad alanına aşağıdaki sınıfı ekleyin:

<Export(GetType(IOperation))>
<ExportMetadata("Symbol", "-"c)>
Public Class Subtract
    Implements IOperation

    Public Function Operate(left As Integer, right As Integer) As Integer Implements IOperation.Operate
        Return left - right
    End Function
End Class
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '-')]
class Subtract : IOperation
{
    public int Operate(int left, int right)
    {
        return left - right;
    }
}

Projeyi derleyin ve çalıştırın. "5-3" gibi bir çıkarma işlemi yazın. Hesap makinesi artık çıkarmanın yanı sıra toplamayı da destekliyor.

SimpleCalculator'ı yeni bir derleme kullanarak genişletme

Kaynak koda sınıf eklemek yeterince basittir, ancak MEF, parçalar için uygulamanın kendi kaynağının dışına bakma olanağı sağlar. Bunu göstermek için, SimpleCalculator'ı değiştirerek bir dizinde ve kendi derlemesinde parçalar için arama yapmanız gerekir; bunun için bir DirectoryCatalog eklemelisiniz.

SimpleCalculator projesine adlı Extensions yeni bir dizin ekleyin. Çözüm düzeyinde değil proje düzeyinde eklediğinizden emin olun. Ardından çözüme adlı ExtendedOperationsyeni bir Sınıf Kitaplığı projesi ekleyin. Yeni proje ayrı bir derlemede toplanacak.

ExtendedOperations projesi için Proje Özellikleri Tasarımcısı'nı açın ve Derle veya Oluştur sekmesine tıklayın. Derleme çıkış yolunu veya Çıkış yolunu SimpleCalculator proje dizinindeki Uzantılar dizininde işaret edecek şekilde değiştirin (..\SimpleCalculator\Extensions\).

Module1.vb veya Program.cs oluşturucuya Program aşağıdaki satırı ekleyin:

catalog.Catalogs.Add(
    New DirectoryCatalog(
        "C:\SimpleCalculator\SimpleCalculator\Extensions"))
catalog.Catalogs.Add(
    new DirectoryCatalog(
        "C:\\SimpleCalculator\\SimpleCalculator\\Extensions"));

Örnek konumu kendi Uzantılar dizininizin konumuyla değiştirin. (Bu mutlak yol yalnızca hata ayıklama amaçlıdır. Bir üretim uygulamasında göreli bir yol kullanırsınız.) DirectoryCatalog artık Extensions dizinindeki tüm derlemelerde bulunan tüm bölümleri oluşturma kapsayıcısına ekleyecektir.

Projede ExtendedOperations ve SimpleCalculator ile System.ComponentModel.Composition için referanslar ekleyin. Sınıf dosyasında, ExtendedOperations için bir Imports veya using yönergesi ekleyin. Visual Basic'te Imports için bir SimpleCalculator deyimi ekleyin. Ardından aşağıdaki sınıfı sınıf ExtendedOperations dosyasına ekleyin:

<Export(GetType(SimpleCalculator.IOperation))>
<ExportMetadata("Symbol", "%"c)>
Public Class Modulo
    Implements IOperation

    Public Function Operate(left As Integer, right As Integer) As Integer Implements IOperation.Operate
        Return left Mod right
    End Function
End Class
[Export(typeof(SimpleCalculator.IOperation))]
[ExportMetadata("Symbol", '%')]
public class Mod : SimpleCalculator.IOperation
{
    public int Operate(int left, int right)
    {
        return left % right;
    }
}

Sözleşmenin eşleşmesi için özniteliğin ExportAttribute ile aynı türe ImportAttributesahip olması gerektiğini unutmayın.

Projeyi derleyin ve çalıştırın. Yeni Mod (%) işlecini test edin.

Sonuç

Bu konu başlığı altında MEF'in temel kavramları ele alınmıştır.

  • Parçalar, kataloglar ve bileşim kapsayıcısı

    Parçalar ve bileşim kapsayıcısı bir MEF uygulamasının temel yapı taşlarıdır. Bölüm, kendisi dahil olmak üzere bir değeri içeri veya dışarı aktaran herhangi bir nesnedir. Katalog, belirli bir kaynaktan bir parça koleksiyonu sağlar. Oluşturma kapsayıcısı, bir katalog tarafından sağlanan parçaları kullanarak birleştirmeyi gerçekleştirir ve içeri aktarmaların dışarı aktarmalara bağlanmasını sağlar.

  • İçeri ve dışarı aktarmalar

    İçeri ve dışarı aktarma işlemleri, bileşenlerin iletişim kurma yoludur. İçeri aktarma işlemiyle, bileşen belirli bir değer veya nesne için bir gereksinim belirtir ve dışarı aktarma ile bir değerin kullanılabilirliğini belirtir. Her içeri aktarma işlemi, sözleşmesi gereği bir dışarı aktarma listesiyle eşleştirilir.

Sonraki Adımlar

Bu örneğin tam kodunu indirmek için simpleCalculator örneğine (Visual Basic) bakın.

Daha fazla bilgi ve kod örnekleri için bkz. Yönetilen Genişletilebilirlik Çerçevesi. MEF türlerinin listesi için ad alanına System.ComponentModel.Composition bakın.