Aracılığıyla paylaş


Taneli başvurular

Bir yöntemi tahıl üzerinde çağırmadan önce bu taneye bir başvuru gerekir. Taneli başvuru, karşılık gelen tanecik sınıfıyla aynı tanecik arabirimini uygulayan bir proxy nesnesidir. Hedef dilimin mantıksal kimliğini (tür ve benzersiz anahtar) kapsüller. Gren başvuruları, hedef dilime çağrı yapmak için kullanılır. Her taneli başvuru tek bir taneye (tek bir tanecik sınıfı örneği) yöneliktir, ancak aynı taneye birden çok bağımsız başvuru oluşturabilir.

Bir taneli başvuru hedef dilimin mantıksal kimliğini temsil ettiğinden, tahılın fiziksel konumundan bağımsızdır ve sistemin tamamen yeniden başlatılmasından sonra bile geçerli kalır. Geliştiriciler diğer .NET nesneleri gibi ayrıntılı başvurular kullanabilir. Bir yönteme geçirilebilir, yöntem dönüş değeri olarak kullanılır ve hatta kalıcı depolamaya kaydedilebilir.

Bir tanecik başvurusu, bir tanenin kimliğini yönteme IGrainFactory.GetGrain<TGrainInterface>(Type, Guid) geçirerek elde edilebilir; burada T tane arabirimidir ve key türün içindeki tahılın benzersiz anahtarıdır.

Aşağıda, yukarıda tanımlanan arabirimin ayrıntılı başvurularının nasıl alındığı IPlayerGrain örnekleri verilmiştir.

Bir taneli sınıfın içinden:

// This would typically be read from an HTTP request parameter or elsewhere.
Guid playerId = Guid.NewGuid();
IPlayerGrain player = GrainFactory.GetGrain<IPlayerGrain>(playerId);

İstemci kodundan Orleans :

// This would typically be read from an HTTP request parameter or elsewhere.
Guid playerId = Guid.NewGuid();
IPlayerGrain player = client.GetGrain<IPlayerGrain>(playerId);

Hububat başvuruları üç bilgi içerir:

  1. Tanecik sınıfını benzersiz olarak tanımlayan tanecik türü.
  2. Bu tanecik sınıfının mantıksal örneğini benzersiz olarak tanımlayan tanecik anahtarı.
  3. Taneli başvurunun uygulaması gereken arabirim .

Not

Tanecik türü ve anahtar , tanecik kimliğini oluşturur.

Yukarıdaki çağrıların IGrainFactory.GetGrain şu üç şeyden yalnızca ikisini kabul ettiğini unutmayın:

  • Hububat başvurusu tarafından uygulanan arabirim , IPlayerGrain.
  • değeri olan playerIdtanecik anahtarı.

Bir taneli başvurunun bir tanecik türü, anahtar ve arabirim içerdiği belirtilmesine rağmen, örnekler yalnızca anahtar ve arabirimle birlikte sağlanırOrleans. Bunun nedeni Orleans , tanecik arabirimleri ve tane türleri arasında bir eşleme tutmasıdır. için tahıl fabrikasına sorduğunuzda, Orleans başvuruyu oluşturabilmesi için ilgili tane türünü bulmak için IShoppingCartGraineşlemesine başvurur. Bu, bir taneli arabirimin yalnızca bir uygulaması olduğunda çalışır, ancak birden çok uygulama varsa, bunları çağrıda GetGrain ayırmanız gerekir. Daha fazla bilgi için sonraki bölüme bakın ve dilim türü çözümlemesini kesinleştirme.

Not

Orleans derleme sırasında uygulamanızdaki her bir taneli arabirim için taneli başvuru uygulama türleri oluşturur. Bu tanecik başvuru uygulamaları sınıfından devralır Orleans.Runtime.GrainReference . GetGrain istenen tanecik arabirimine karşılık gelen oluşturulan Orleans.Runtime.GrainReference uygulamanın örneklerini döndürür.

Kesinleştirici tanecik türü çözünürlüğü

Aşağıdaki örnekte olduğu gibi bir taneli arabirimin birden çok uygulaması olduğunda, Orleans bir taneli başvuru oluştururken hedeflenen uygulamayı belirlemeye çalışır. Arabiriminin iki uygulamasının ICounterGrain bulunduğu aşağıdaki örneği göz önünde bulundurun:

public interface ICounterGrain : IGrainWithStringKey
{
    ValueTask<int> UpdateCount();
}

public class UpCounterGrain : ICounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(++_count); // Increment count
}

public class DownCounterGrain : ICounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(--_count); // Decrement count
}

Aşağıdaki çağrısı GetGrain bir özel durum oluşturur çünkü Orleans kesinlik sınıflarından biriyle nasıl eşleneceklerini ICounterGrain kesin olarak bilmez.

// This will throw an exception: there is no unambiguous mapping from ICounterGrain to a grain class.
ICounterGrain myCounter = grainFactory.GetGrain<ICounterGrain>("my-counter");

System.ArgumentException Aşağıdaki iletiyle bir oluşturulur:

Unable to identify a single appropriate grain type for interface ICounterGrain. Candidates: upcounter (UpCounterGrain), downcounter (DownCounterGrain)

Hata iletisi, istenen tanecik arabirim türüyle ICounterGraineşleşen hangi tanecik uygulamasına Orleans sahip olduğunu bildirir. Hem tanecik türü adlarını (upcounter ve downcounter) hem de tanecik sınıflarını (UpCounterGrain ve DownCounterGrain) gösterir.

Not

Önceki hata iletisindeki ve downcounteriçindeki tanecik türü adları, upcounter sırasıyla tanecik sınıf adlarından UpCounterGrain türetilirDownCounterGrain. Bu, içindeki Orleans varsayılan davranıştır ve grain sınıfına bir [GrainType(string)] öznitelik eklenerek özelleştirilebilir. Örneğin:

[GrainType("up")]
public class UpCounterGrain : IUpCounterGrain { /* as above */ }

Bu belirsizliği çözmek için aşağıdaki alt bölümlere ayrıntılı bir şekilde bakın.

Benzersiz işaretçi arabirimlerini kullanarak dilim türlerini kesinleştirme

Bu taneleri kesinleştirmenin en net yolu, onlara benzersiz tane arabirimleri vermektir. Örneğin, aşağıdaki örnekte olduğu gibi arabirimini IUpCounterGrain sınıfına UpCounterGrain ekler ve arabirimini IDownCounterGrain sınıfa DownCounterGrain eklersek, belirsiz ICounterGrain türü geçirmek yerine çağrıyı geçirerek IUpCounterGrain veya IDownCounterGrain çağrısına GetGrain<T> doğru tanecik başvuruyu çözümleyebiliriz.

public interface ICounterGrain : IGrainWithStringKey
{
    ValueTask<int> UpdateCount();
}

// Define unique interfaces for our implementations
public interface IUpCounterGrain : ICounterGrain, IGrainWithStringKey {}
public interface IDownCounterGrain : ICounterGrain, IGrainWithStringKey {}

public class UpCounterGrain : IUpCounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(++_count); // Increment count
}

public class DownCounterGrain : IDownCounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(--_count); // Decrement count
}

Her iki taneye de başvuru oluşturmak için aşağıdaki kodu göz önünde bulundurun:

// Get a reference to an UpCounterGrain.
ICounterGrain myUpCounter = grainFactory.GetGrain<IUpCounterGrain>("my-counter");

// Get a reference to a DownCounterGrain.
ICounterGrain myDownCounter = grainFactory.GetGrain<IDownCounterGrain>("my-counter");

Not

Önceki örnekte, aynı anahtara ancak farklı tanecik türlerine sahip iki taneli başvuru oluşturdunuz. değişkeninde myUpCounter depolanan ilk, kimliğine upcounter/my-countersahip tanecik başvurusudur. değişkeninde myDownCounter depolanan ikinci, kimliğine downcounter/my-countersahip tanecik başvurusudur. Bir tanecik türünü benzersiz olarak tanımlayan tahıl türü ve tane anahtarı birleşimidir. Bu nedenle, myUpCounter farklı myDownCounter tahıllara bakın.

Bir tanecik sınıfı ön eki sağlayarak dilim türlerini kesinleştirme

için bir taneli sınıf adı ön eki IGrainFactory.GetGrainsağlayabilirsiniz, örneğin:

ICounterGrain myUpCounter = grainFactory.GetGrain<ICounterGrain>("my-counter", grainClassNamePrefix: "Up");
ICounterGrain myDownCounter = grainFactory.GetGrain<ICounterGrain>("my-counter", grainClassNamePrefix: "Down");

Adlandırma kuralını kullanarak varsayılan grain uygulamasını belirtme

Aynı hub'lı arabirimin birden çok uygulamasını belirsizleştirirken, Orleans arabirim adından baştaki bir 'I' öğesinin çıkarılması kuralını kullanarak bir uygulama seçer. Örneğin, arabirim adı ICounterGrain ise ve iki uygulama CounterGrain varsa ve Orleans DownCounterGrainaşağıdaki örnekte olduğu gibi öğesine başvuru ICounterGrainistendiğinde öğesini seçerCounterGrain:

/// This will refer to an instance of CounterGrain, since that matches the convention.
ICounterGrain myUpCounter = grainFactory.GetGrain<ICounterGrain>("my-counter");

Öznitelik kullanarak varsayılan tanecik türünü belirtme

Öznitelik, Orleans.Metadata.DefaultGrainTypeAttribute aşağıdaki örnekte olduğu gibi bu arabirim için varsayılan uygulamanın tanecik türünü belirtmek üzere bir taneli arabirime eklenebilir:

[DefaultGrainType("up-counter")]
public interface ICounterGrain : IGrainWithStringKey
{
    ValueTask<int> UpdateCount();
}

[GrainType("up-counter")]
public class UpCounterGrain : ICounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(++_count); // Increment count
}

[GrainType("down-counter")]
public class DownCounterGrain : ICounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(--_count); // Decrement count
}
/// This will refer to an instance of UpCounterGrain, due to the [DefaultGrainType("up-counter"')] attribute
ICounterGrain myUpCounter = grainFactory.GetGrain<ICounterGrain>("my-counter");

Çözümlenen tanecik kimliğini sağlayarak dilim türlerini kesinleştirme

bazı aşırı yüklemeleri IGrainFactory.GetGrain türünde Orleans.Runtime.GrainIdbir bağımsız değişkeni kabul eder. Bu aşırı yüklemeleri kullanırken, Orleans bir arabirim türünden bir tanecik türüne eşlemesi gerekmez ve bu nedenle çözülecek bir belirsizlik yoktur. Örnek:

public interface ICounterGrain : IGrainWithStringKey
{
    ValueTask<int> UpdateCount();
}

[GrainType("up-counter")]
public class UpCounterGrain : ICounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(++_count); // Increment count
}

[GrainType("down-counter")]
public class DownCounterGrain : ICounterGrain
{
    private int _count;

    public ValueTask<string> UpdateCount() => new(--_count); // Decrement count
}
// This will refer to an instance of UpCounterGrain, since "up-counter" was specified as the grain type
// and the UpCounterGrain uses [GrainType("up-counter")] to specify its grain type.
ICounterGrain myUpCounter = grainFactory.GetGrain<ICounterGrain>(GrainId.Create("up-counter", "my-counter"));