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:
- Tanecik sınıfını benzersiz olarak tanımlayan tanecik türü.
- Bu tanecik sınıfının mantıksal örneğini benzersiz olarak tanımlayan tanecik anahtarı.
- 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
playerId
tanecik 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 IShoppingCartGrain
eş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 ICounterGrain
eş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 downcounter
iç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-counter
sahip tanecik başvurusudur. değişkeninde myDownCounter
depolanan ikinci, kimliğine downcounter/my-counter
sahip 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 DownCounterGrain
aşağıdaki örnekte olduğu gibi öğesine başvuru ICounterGrain
istendiğ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"));