Merhaba,
Injection uygulama yöntemlerinden olan Constructor Injection – Method Injection ve Property Injection ile ilgili senaryoya uygun bir örnek yapacağız.
1-) Constructor Injection
https://github.com/erolakgul/DependencyInjectionEx url inde main branch altındaki yapı constructor injection yöntemini barındırıyor olacak.
Kısaca açıklamak gerekirse;
Controller a gönderilecek sipariş ile ilgili bilgileri kaydetmesi ile ilgili bir action ı var. Bunun için ihtiyacı olan IOrderRepository arayüzünü constructor injection yöntemi ile kullanıyor.

Constructor injection yönteminde di service registration işlemini console uygulamalarında dependencyinjection paketi ile sağlıyoruz. CustomServiceProvider isimli class ımızda serviceprovider nesnesinde kendi nesnelerimizi register ediyoruz. Daha henüz derleme aşamasında interface i çağırdığımızda bize ne vermesi gerektiğini söylemek için tabi… Runtime da aşağıdaki hatayı alırız yoksa.

Uygulama servisi altında controller da OrderController isimli bir class ımız olacak. bu class constructor injection ı hali hazırda uyguluyor olacak.

OrderController içeriği;

private readonly IOrderRepository _orderRepository;
public OrderController(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public string Create(Orders orders)
{
_orderRepository.Create(orders);
return string.Empty;
}
CustomServiceProvider içeriği;

public static class CustomServiceProvider
{
public static ServiceProvider CreateServices()
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IOrderRepository, OrderRepository>()
.BuildServiceProvider();
return serviceProvider;
}
}
Data klasörü altında order repo su ile ile ilgili sözleşme ve uygulaması mevcut.

interface içeriği;

onu uygulayan class ın içeriği;

public void Create(Orders orders)
{
Console.WriteLine($"Order has been saved successfully..\n");
Console.WriteLine($"{orders.ID} numbered Order Summary :");
Console.WriteLine("----------------------------");
foreach ( var order in orders.OrderItems)
{
Console.WriteLine($"{order.Amount} amount {order.ProductName}");
}
}
son olarak core klasörü altında da;
Sipariş ile ilgili head ve item bilgilerini tutacak classlar var;

Order class içeriği;

OrderItems class içeriği;

ana uygulama class içeriğimiz ise aşağıdaki gibi şuan;

öncelikle serviceprovider a erişiyoruz, dönen nesnelerden IOrder ı istiyorum, sonra da onu OrderController ın yapıcı methoduna gönderiyorum.Böylece daha henüz OrderController ın oluşturulma aşamasında , ordercontroller altındaki tüm methodlarda IOrder nesnesini kullanabilir hale geliyorum.
Bu hali ile uygulamayı çalıştırdığımızda siparişi kaydedebildiğimizi görüyoruz.

2-) Method Injection
methodinject isimli yeni bir branch açıyorum.
Senaryo şu şekilde, sipariş başarıyla oluşturulursa, email göndermek.
AppService altında Communication isimli bir klasör daha açıp, ISender isimli bir servis ile, onu inherit eden email servisi ekliyorum.

ISender içeriği;

Email servis içeriği;

implement işlemine repodan başlıyoruz.
A-) NotifyTotalExpense isimli bir sözleşme daha ekleyip, ISender isimli interface i parametre olarak ekliyoruz.

B-) bu repoyu inherit eden sınıfta, methodu implement edip değişikliği yapıyoruz.

C-) OrderController altındaki Notify isimli methotta(asp de action gibi düşünebiliriz), bildirim gönderilmesi için NotifyTotalExpense isimli repo methodu çağırılıyor. İhtiyacı olan ISenderService nesnesinin EmailService ile gönderimi sonrasında çalışır hale geliyor. Constructor Injection yöntemindeki “servisi kayıt etme” (dependency injection service registration) işlemi methoda o nesnenin gönderimi ile sağlanmış oluyor.

D-) çağırma aşamasına geldiğimize göre, son olarak da create controller ından true değer dönerse bilgilendirme gönder şeklinde çağrımızı yapıyoruz.

bu hali ile çalıştırdığımızda;

3-) Property Injection
yine main den türetilmiş propertyinject isimli yeni bir branch açıyorum.
Bu sefer ki senaryo şu şekilde, create aşamasında siparişi geçen kişinin adı cache lenecek, tabi bir şartla 🙂
Application Service altında Cache isimli bir klasör açıp interface ve onu kullanan class ı oluşturuyorum.

IOrderRepository altına bu yeni oluşturduğum ICacheService interfaci ni bir property sözleşme olarak ekliyorum.

IOrder ı implemente eden class altına da bu yeni özeliği implemente ediyorum default olarak

cache lemek istediğim müşteri adı bilgisini create methodu altında aşağıdaki gibi kodluyorum. cacheService property si repo oluştuğu andaki bilgilerle değil ise, müşteri adı cache lenecek şekilde şuan.

çağırma aşamasında ise şu değişiklikleri yapmamız gerekiyor.

eğer aşağıdaki blok ile cacheservice nesnesini register edersek;
_orderRepository.cacheService = new CacheService();
çıktı şu şekilde olur;

eğer etmezsek de ICacheService isimli arayüzü kullanamaz hale gelir. Dolayısıyla method içerisinde bu arayüzün bağımlılığı dışarıdan gelecek olan property ile değiştirilmiş oldu.
