Bir önceki yazılarımdan biri olan MVC Projesinde Dependency Injection başlıklı yazıda MVC uygulamasında Controller sınıfı içerisine dışarıdan bağımlılıkların enjekte edilmesini incelemeye çalışmıştık. Bu yazımızda ise Asp.Net MVC Web Api uygulaması üzerinde Dependency Injection işlemini uygulamaya çalışacağız.
MVC uygulamasında Controller sınıfları System.Web.Mvc.Controller tipinden türetilirken API Controller sınıfları System.Web.Http.ApiController tipinden türetilmiştir. Bu nedenle Web API üzerinde Dependency Injection uygularken bir önceki örnek uygulamadaki yöntemden daha farklı bir yöntem kullanacağız.
public class ValuesController : ApiController { readonly IProductRepository productRepository; public ValuesController(IProductRepository productRepository) { this.productRepository = productRepository; } public IEnumerable<string> Get() { return productRepository.GetValues(); } }
API içerisine bağımlılıkları enjekte ederken IProductRepository interface tipini uygulayan(implemente eden) sınıfları göndermeye dikkat edeceğiz.
WEB API içerisinde Dependency Injection işlemini gerçekleştirmek için yine MVC’de olduğu gibi IoC container kütüphanelerinden faydalanmamız gerekiyor.
WEB API projelerinde Controller sınıflarının parametreli şekilde çalışabilmesi için bazı ayarlamaları yapmamız gerekecek. Bu ayarlamalardan biri, System.Web.Http alanında bulunan GlobalConfiguration statik sınıfındaki DependencyResolver özelliğinin düzenlenmesi olacaktır. Bu sayede WEB API, resolver mekanizmasını tanıyacaktır. Bu ayarlama Global.asax.cs dosyası içerisinde yapılmaktadır. Tanımlama:
public class WebApiApplication : HttpApplication { protected void Application_Start() { // Diğer kodlar... GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(CreateKernel()); } private IKernel CreateKernel() { IKernel kernel = new StandardKernel(); kernel.Bind<IProductRepository>().To<ProductRepository>(); return kernel; } }
NinjectDependencyResolver adında bir sınıf hazırlıyoruz ve yukarıdaki gibi DependencyResolver özelliğine atıyoruz. DependencyResolver özelliği IDependencyResolver tipindedir. Bu sebeple NinjectDependencyResolver sınıfı da IDependencyReolver tipini uygulamalıdır.
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver { private readonly IKernel kernel; public NinjectDependencyResolver(IKernel kernel): base(kernel) { this.kernel = kernel; } public IDependencyScope BeginScope() { return new NinjectDependencyScope(kernel.BeginBlock()); } }
NinjectDependencyResolver sınıfını aynı zamanda NinjectDependencyScope sınıfından türetiyoruz. Bunun sebebi ise IDependencyResolver interface tipinin barındırdığı BeginScope() metodudur. Bu metodun bir şekilde doldurulması gerekmektedir. NinjectDependencyScope tipi de kendi oluşturmuş olduğumuz bir sınıf olacaktır. Bu sınıfı de şu şekilde oluşturabiliriz.
public class NinjectDependencyScope : IDependencyScope { IResolutionRoot resolver; public NinjectDependencyScope( IResolutionRoot resolver) { this.resolver = resolver; } public void Dispose() { IDisposable disposable = resolver as IDisposable; if (disposable!=null) { disposable.Dispose(); } resolver = null; } public object GetService(Type serviceType) { if (resolver==null) { throw new ObjectDisposedException("this", "This scope has been disposed"); } return resolver.TryGet(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { if (resolver == null) { throw new ObjectDisposedException("this", "This scope has been disposed"); } return resolver.GetAll(serviceType); } }
Son aşamayı da bu şekilde tamamladıktan sonra projemiz çalışabilir hale gelmiş demektir.
Projenin örnek kodlarını SkyDrive üzerinden paylaşıyorum.
Kaynak Kod: Burada
Merhaba, Şuanda üstünde çalıştığım projede hem controller dan hemde apicontroller dan türemiş sınıflarımda ninject kullanmak istiyorum ama sadece ya controllerda ya da sizin yazdığınız kodları kullanarak sadece apicontrollerlarımda kullanabiliyorum. İkisi içinde kullanmak için nasıl bir yol izlemem gerekiyor?
Teşekkürler
MVC Web projesi ile Web API arasında dependency kullanımı arasında biraz farklılıklar var. http://www.bayramucuncu.com/?s=mvc+dependency buradaki yazıda MVC projesi üzerinde dependency injection kullanımını gösteren bir örnek mevcut.
@bucuncu
Haklısınız ama ikisini bir arada kullanmam gerekiyordu ve şöyle çözdüm sorunumu eğer aynı sorunu yaşayanlar olursa çözüm olabilir. Öncelikle Managa Nuget Package ile Ninject.MVC3 ü indirdim(MVC4 ü destekliyor). Sonra App_Start – NinjectWebCommon.cs Start() fonksiyonunun içine “GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(CreateKernel());” kopyaladım. Aynı class içindeki RegisterService fonksiyonun içine “kernel.Bind().To();” gibi tanımlamalarımı yaptım ve sonra sizin oluşturmuş olduğunuz NinjectContainer.cs sınıfını oluşturdum. Bu şekilde hem Web Api den hem de MVC Web projesinden referansları bağlayabildim.
@Berdan sorunun çözülmüş olmasına sevindim. Katkıların için teşekkürler.