Bağımlılık ekleme
İpucu
Bu içerik, .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak bulunan .NET MAUIKullanan Kurumsal Uygulama Desenleri adlı e-Kitap'tan bir alıntıdır.
Genellikle, bir nesne örneği oluşturulurken bir sınıf oluşturucu çağrılır ve nesnenin ihtiyaç duyduğu tüm değerler oluşturucuya bağımsız değişken olarak geçirilir. Bu, oluşturucu ekleme olarak bilinen bir bağımlılık ekleme örneğidir. Nesnenin ihtiyaç duyduğu bağımlılıklar oluşturucuya eklenir.
Bağımlılık ekleme, arabirim türleri olarak bağımlılıkları belirterek somut türlerin bu türlere bağlı koddan ayırmasını sağlar. Genellikle, arabirimler ve soyut türler ile bu türleri uygulayan veya genişleten somut türler arasındaki kayıtların ve eşlemelerin listesini tutan bir kapsayıcı kullanır.
Özellik ayarlayıcı ekleme ve yöntem çağrı ekleme gibi başka bağımlılık ekleme türleri de vardır, ancak bunlar daha az görülür. Bu nedenle, bu bölüm yalnızca bağımlılık ekleme kapsayıcısı ile oluşturucu ekleme işlemi gerçekleştirmeye odaklanacaktır.
Bağımlılık eklemeye giriş
Bağımlılık ekleme, Denetimin Ters Çevrilmesi (IoC) deseninin özelleştirilmiş bir sürümüdür ve burada ters çevrilen sorun, gerekli bağımlılığı elde etme işlemidir. Bağımlılık ekleme ile başka bir sınıf çalışma zamanında bir nesneye bağımlılık eklemekle sorumludur. Aşağıdaki kod örneği bağımlılık ekleme kullanılırken sınıfın ProfileViewModel
nasıl yapılandırıldığını gösterir:
private readonly ISettingsService _settingsService;
private readonly IAppEnvironmentService _appEnvironmentService;
public ProfileViewModel(
IAppEnvironmentService appEnvironmentService,
IDialogService dialogService,
INavigationService navigationService,
ISettingsService settingsService)
: base(dialogService, navigationService, settingsService)
{
_appEnvironmentService = appEnvironmentService;
_settingsService = settingsService;
// Omitted for brevity
}
Oluşturucu, ProfileViewModel
başka bir sınıf tarafından eklenen bağımsız değişkenler olarak birden çok arabirim nesnesi örneği alır. sınıfındaki ProfileViewModel
tek bağımlılık arabirim türleridir. Bu nedenle sınıfı, ProfileViewModel
arabirim nesnelerinin örneğini oluşturmadan sorumlu olan sınıf hakkında herhangi bir bilgiye sahip değildir. Arabirim nesnelerinin örneğini oluşturma ve sınıfına ProfileViewModel
eklemeden sorumlu sınıf, bağımlılık ekleme kapsayıcısı olarak bilinir.
Bağımlılık ekleme kapsayıcıları, sınıf örneklerinin örneğini oluşturacak ve kapsayıcının yapılandırmasına göre yaşam sürelerini yönetecek bir tesis sağlayarak nesneler arasındaki bağlantıyı azaltır. Nesne oluşturma sırasında kapsayıcı, nesnenin gerektirdiği tüm bağımlılıkları buna ekler. Bu bağımlılıklar henüz oluşturulmadıysa kapsayıcı önce bağımlılıklarını oluşturur ve çözer.
Bağımlılık ekleme kapsayıcısı kullanmanın çeşitli avantajları vardır:
- Kapsayıcı, bir sınıfın bağımlılıklarını bulması ve yaşam sürelerini yönetmesi gereksinimini ortadan kaldırır.
- Kapsayıcı, sınıfı etkilemeden uygulanan bağımlılıkların eşlenmesine olanak tanır.
- Kapsayıcı, bağımlılıkların sahte olmasına izin vererek test edilebilirliği kolaylaştırır.
- Kapsayıcı, uygulamaya yeni sınıfların kolayca eklenmesini sağlayarak sürdürülebilirliği artırır.
MVVM kullanan bir .NET MAUI uygulaması bağlamında, bağımlılık ekleme kapsayıcısı genellikle görünümleri kaydetmek ve çözümlemek, görünüm modellerini kaydetmek ve çözümlemek, hizmetleri kaydetmek ve görünüm modellerine eklemek için kullanılır.
.NET'te birçok bağımlılık ekleme kapsayıcısı vardır; eShop çok platformlu uygulaması, uygulamadaki görünümlerin, görünüm modellerinin ve hizmet sınıflarının örneğini yönetmek için kullanır Microsoft.Extensions.DependencyInjection
. Microsoft.Extensions.DependencyInjection
gevşek bağlantılı uygulamalar derlemeyi kolaylaştırır ve tür eşlemelerini ve nesne örneklerini kaydetme, nesneleri çözümleme, nesne yaşam sürelerini yönetme ve bağımlı nesneleri çözümlediğini nesnelerin oluşturucularına ekleme yöntemleri de dahil olmak üzere bağımlılık ekleme kapsayıcılarında yaygın olarak bulunan tüm özellikleri sağlar. hakkında Microsoft.Extensions.DependencyInjection
daha fazla bilgi için bkz . .NET'te bağımlılık ekleme.
.NET'te MAUIsınıfıMauiProgram
, nesnesi MauiAppBuilder
oluşturmak için yöntemine CreateMauiApp
çağrı yapacaktır. MauiAppBuilder
nesnesi, bağımlılık ekleme için görünümler, görünüm modelleri ve hizmetler gibi bileşenlerimizi kaydedebileceğiniz bir yer sağlayan türünde IServiceCollection
bir Services
özelliğine sahiptir. yöntemi çağrıldığında, özelliğine Services
kayıtlı tüm bileşenler bağımlılık ekleme kapsayıcısına MauiAppBuilder.Build
sağlanacaktır.
Çalışma zamanında, kapsayıcının istenen nesneler için bunların örneğini oluşturabilmesi için hangi hizmet uygulamasının istenmekte olduğunu bilmesi gerekir. eShop çok platformlu uygulamasında, bir ProfileViewModel
nesnenin IAppEnvironmentService
örneğini oluşturabilmesi için önce , IDialogService
, INavigationService
ve ISettingsService
arabirimlerinin çözümlenmesi gerekir. Bu, kapsayıcının aşağıdaki eylemleri gerçekleştirmesini içerir:
- Arabirimi uygulayan bir nesnenin örneğini oluşturma. Bu, kayıt olarak bilinir.
- Gerekli arabirimi ve nesnesini uygulayan nesnenin örneğini oluşturma
ProfileViewModel
. Bu çözüm olarak bilinir.
Sonunda uygulama nesnesini kullanmayı ProfileViewModel
tamamlar ve çöp toplama için kullanılabilir hale gelir. Bu noktada, diğer sınıflar aynı örneği paylaşmıyorsa, atık toplayıcı kısa süreli arabirim uygulamalarını atmalıdır.
Kayıt
Bağımlılıkların bir nesneye eklenebilmesi için önce bağımlılık türlerinin kapsayıcıya kaydedilmesi gerekir. Bir türün kaydedilmesi, kapsayıcıyı bir arabirim ve arabirimi uygulayan somut bir tür geçirmeyi içerir.
Kapsayıcıdaki türleri ve nesneleri kod aracılığıyla kaydetmenin iki yolu vardır:
- Kapsayıcıya bir tür veya eşleme kaydedin. Bu, geçici kayıt olarak bilinir. Gerektiğinde kapsayıcı, belirtilen türün bir örneğini oluşturur.
- Kapsayıcıdaki mevcut bir nesneyi tekil olarak kaydedin. Gerektiğinde, kapsayıcı var olan nesneye bir başvuru döndürür.
Not
Bağımlılık ekleme kapsayıcıları her zaman uygun değildir. Bağımlılık ekleme, küçük uygulamalar için uygun veya yararlı olmayan ek karmaşıklık ve gereksinimler sunar. Bir sınıfın herhangi bir bağımlılığı yoksa veya diğer türler için bir bağımlılık değilse, bunu kapsayıcıya koymak mantıklı olmayabilir. Ayrıca, bir sınıfın türüne tam sayı olan ve hiçbir zaman değişmeyecek tek bir bağımlılık kümesi varsa, bunu kapsayıcıya koymak mantıklı olmayabilir.
Bağımlılık ekleme gerektiren türlerin kaydı, bir uygulamadaki tek bir yöntemde gerçekleştirilmelidir. Bu yöntem, sınıfları arasındaki bağımlılıkların farkında olduğundan emin olmak için uygulamanın yaşam döngüsünün başlarında çağrılmalıdır. eShop çok platformlu uygulaması bu MauiProgram.CreateMauiApp
yöntemi gerçekleştirir. Aşağıdaki kod örneğinde, eShop çok platformlu uygulamasının sınıfında nasıl bildir CreateMauiApp
olduğu MauiProgram
gösterilmektedir:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
=> MauiApp.CreateBuilder()
.UseMauiApp<App>()
// Omitted for brevity
.RegisterAppServices()
.RegisterViewModels()
.RegisterViews()
.Build();
}
yöntemi, MauiApp.CreateBuilder
bağımlılıklarımızı kaydetmek için kullanabileceğimiz bir MauiAppBuilder
nesne oluşturur. eShop çok platformlu uygulamadaki birçok bağımlılığın kaydedilmesi gerektiğinden , RegisterViewModels
ve uzantı yöntemleriRegisterAppServices
, düzenli ve RegisterViews
sürdürülebilir bir kayıt iş akışı sağlamaya yardımcı olmak için oluşturulmuştur. Aşağıdaki kod yöntemini RegisterViewModels
gösterir:
public static MauiAppBuilder RegisterViewModels(this MauiAppBuilder mauiAppBuilder)
{
mauiAppBuilder.Services.AddSingleton<ViewModels.MainViewModel>();
mauiAppBuilder.Services.AddSingleton<ViewModels.LoginViewModel>();
mauiAppBuilder.Services.AddSingleton<ViewModels.BasketViewModel>();
mauiAppBuilder.Services.AddSingleton<ViewModels.CatalogViewModel>();
mauiAppBuilder.Services.AddSingleton<ViewModels.ProfileViewModel>();
mauiAppBuilder.Services.AddTransient<ViewModels.CheckoutViewModel>();
mauiAppBuilder.Services.AddTransient<ViewModels.OrderDetailViewModel>();
mauiAppBuilder.Services.AddTransient<ViewModels.SettingsViewModel>();
mauiAppBuilder.Services.AddTransient<ViewModels.CampaignViewModel>();
mauiAppBuilder.Services.AddTransient<ViewModels.CampaignDetailsViewModel>();
return mauiAppBuilder;
}
Bu yöntem bir örneğini MauiAppBuilder
alır ve görünüm modellerimizi kaydetmek için özelliğini kullanabiliriz Services
. Uygulamanızın gereksinimlerine bağlı olarak, farklı yaşam süresine sahip hizmetler eklemeniz gerekebilir. Aşağıdaki tabloda, bu farklı kayıt ömürlerini ne zaman seçmek isteyebileceğiniz hakkında bilgi sağlanmaktadır:
Metot | Açıklama |
---|---|
AddSingleton<T> |
Uygulamanın ömrü boyunca kalacak olan nesnenin tek bir örneğini oluşturur. |
AddTransient<T> |
Çözümleme sırasında istendiğinde nesnenin yeni bir örneğini oluşturur. Geçici nesnelerin önceden tanımlanmış bir ömrü yoktur, ancak genellikle konaklarının ömrünü izler. |
Not
Görünüm modelleri bir arabirimden devralınmadığından, yalnızca ve AddTransient<T>
yöntemlerine somut türlerinin AddSingleton<T>
sağlanması gerekir.
CatalogViewModel
, uygulamanın köküne yakın bir şekilde kullanılır ve her zaman kullanılabilir olmalıdır, bu nedenle ile kaydetmek AddSingleton<T>
yararlı olur. ve gibi CheckoutViewModel
OrderDetailViewModel
diğer görünüm modelleri, uygulamada duruma göre gider veya daha sonra kullanılır. Her zaman kullanılamayabilecek bir bileşeniniz olduğunu bildiğinizi varsayalım. Bu durumda, bellek veya hesaplama açısından yoğunsa veya tam zamanında veri gerektiriyorsa, kayıt için AddTransient<T>
daha iyi bir aday olabilir.
Hizmet eklemenin bir diğer yaygın yolu da ve AddTransient<TService, TImplementation>
yöntemlerini kullanmaktırAddSingleton<TService, TImplementation>
. Bu yöntemler iki giriş türü alır: arabirim tanımı ve somut uygulama. Bu tür bir kayıt, arabirimleri temel alan hizmetler uyguladığınız durumlar için en iyisidir. Aşağıdaki kod örneğinde, arabirimimizi ISettingsService
aşağıdaki uygulamayı kullanarak SettingsService
kaydediyoruz:
public static MauiAppBuilder RegisterAppServices(this MauiAppBuilder mauiAppBuilder)
{
mauiAppBuilder.Services.AddSingleton<ISettingsService, SettingsService>();
// Omitted for brevity...
}
Tüm hizmetler kaydedildikten sonra, MauiAppBuilder.Build
bağımlılık ekleme kapsayıcımızı MauiApp
oluşturmak ve tüm kayıtlı hizmetlerle doldurmak için yöntemi çağrılmalıdır.
Önemli
Build
Yöntem çağrıldıktan sonra bağımlılık ekleme kapsayıcısı sabittir ve artık güncelleştirilemez veya değiştirilemez. çağrısı Build
yapılmadan önce uygulamanızda ihtiyacınız olan tüm hizmetlerin kayıtlı olduğundan emin olun.
Çözüm
Bir tür kaydedildikten sonra çözümlenebilir veya bağımlılık olarak eklenebilir. Bir tür çözümlenirken ve kapsayıcının yeni bir örnek oluşturması gerektiğinde, tüm bağımlılıkları örneğe ekler.
Genellikle, bir tür çözümlendiğinde üç şeyden biri gerçekleşir:
- Tür kaydedilmemişse kapsayıcı bir özel durum oluşturur.
- Tür tekil olarak kaydedildiyse, kapsayıcı singleton örneğini döndürür. Tür ilk kez çağrılırsa, kapsayıcı gerekirse bunu oluşturur ve buna bir başvuru tutar.
- Tür geçici olarak kaydedildiyse kapsayıcı yeni bir örnek döndürür ve buna bir başvuru sağlamaz.
.NET MAUI , kayıtlı bileşenleri ihtiyaçlarınıza göre çözümlemek için çeşitli yollar sunar. Bağımlılık ekleme kapsayıcısına erişim kazanmanın en doğrudan yolu kullanarak Handler.MauiContext.Services
kullanmaktırElement
. Bunun bir örneği aşağıda gösterilmiştir:
var settingsService = this.Handler.MauiContext.Services.GetServices<ISettingsService>();
Bir hizmeti oluşturucunuzun Element
içinden Element
veya dışından çözümlemeniz gerekiyorsa bu yararlı olabilir.
Dikkat
özelliğinin Handler
Element
null olma olasılığı vardır, bu nedenle bu durumlarla ilgilenmeniz gerekebileceğini unutmayın. Daha fazla bilgi için lütfen Microsoft Belge Merkezi'nin İşleyici yaşam döngüsü bölümüne bakın.
.NET MAUIdenetimini kullanıyorsanızShell
, gezinti sırasında nesnelerimizi oluşturmak için bağımlılık ekleme kapsayıcısını örtük olarak çağırır. Denetimimizi Shell
ayarlarken yöntemi, Routing.RegisterRoute
aşağıdaki örnekte gösterildiği gibi bir yol yolunu ile View
bağlar:
Routing.RegisterRoute("Filter", typeof(FiltersView));
Gezinti sırasında Shell
, kayıtlarını FiltersView
arar ve herhangi biri bulunursa, bu görünümü oluşturur ve oluşturucuya bağımlılıkları ekler. Aşağıdaki kod örneğinde gösterildiği gibi içine CatalogViewModel
eklenecektir FiltersView
:
namespace eShop.Views;
public partial class FiltersView : ContentPage
{
public FiltersView(CatalogViewModel viewModel)
{
BindingContext = viewModel;
InitializeComponent();
}
}
İpucu
Bağımlılık ekleme kapsayıcısı, görünüm modeli örnekleri oluşturmak için mükemmeldir. Görünüm modelinin bağımlılıkları varsa, gerekli hizmetlerin oluşturulmasını ve eklenmesini işler. Görünüm modellerinizi ve bunların sahip olabileceği bağımlılıkları sınıfındaki yöntemiyle kaydettiğinizden CreateMauiApp
MauiProgram
emin olun.
Özet
Bağımlılık ekleme, somut türlerin bu türlere bağlı koddan ayırmasını sağlar. Genellikle, arabirimler ve soyut türler ile bu türleri uygulayan veya genişleten somut türler arasındaki kayıtların ve eşlemelerin listesini tutan bir kapsayıcı kullanır.
Microsoft.Extensions.DependencyInjection
gevşek bir şekilde bağlanmış uygulamalar oluşturulmasını kolaylaştırır ve tür eşlemelerini ve nesne örneklerini kaydetme, nesneleri çözümleme, nesne yaşam sürelerini yönetme ve çözümlediğinden nesne oluşturucularına bağımlı nesneler ekleme yöntemleri de dahil olmak üzere bağımlılık ekleme kapsayıcılarında yaygın olarak bulunan tüm özellikleri sağlar.