Dependency Injection in WebAPI with Castle Windsor - c#

I want to implement Dependency Injection in WebApi application using Castle Windsor. I have following sample code -
Interface -
public interface IWatch
{
{
DateTime GetTime();
}
}
Following Watch class implements IWatch Interface -
public class Watch:IWatch
{
public DateTime GetTime()
{
return DateTime.Now;
}
}
WebApi Controller - WatchController as below -
public class WatchController : ApiController
{
private readonly IWatch _watch;
public WatchController()
{
_watch = new Watch();
}
//http://localhost:48036/api/Watch
public string Get()
{
var message = string.Format("The current time on the server is: {0}", _watch.GetTime());
return message;
}
}
Currently I am initiating IWatch object with Watch in WatchController constructor. I want to remove dependency of initializing IWatch inside constructor using Windsor Castle dependency injection principle.
Can anybody provide me the steps to implement dependency injection in this case of WebApi? Thanks in advance!

CodeCaster, Noctis and Cristiano thank you for all your help and guidance..
I just got the solution for my above query -
The first step is to use nuget to install the Windsor.Castle packages in the WebApi solution.
Consider the following code snippet -
Interface IWatch.cs
public interface IWatch
{
DateTime GetTime();
}
Class Watch.cs
public class Watch:IWatch
{
public DateTime GetTime()
{
return DateTime.Now;
}
}
The ApiController WatchController.cs is defined as follows: -
public class WatchController : ApiController
{
private readonly IWatch _watch;
public WatchController(IWatch watch)
{
_watch = watch;
}
public string Get()
{
var message = string.Format("The current time on the server is: {0}", _watch.GetTime());
return message;
}
}
In the controller we have injected the dependency through IWatch object in the WatchController constructor. I have used IDependencyResolver and IDependencyScope to achieve dependency injection in web api.
The IDependencyResolver interface is used to resolve everything outside a request scope.
WindsorDependencyResolver.cs
internal sealed class WindsorDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer _container;
public WindsorDependencyResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
WindsorDependencyScope.cs
internal sealed class WindsorDependencyScope : IDependencyScope
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
WatchInstaller.cs
Installers are simply types that implement the IWindsorInstaller interface. The interface has a single method called Install. The method gets an instance of the container, which it can then register components with using fluent registration API:
public class WatchInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//Need to Register controllers explicitly in your container
//Failing to do so Will receive Exception:
//> An error occurred when trying to create //a controller of type
//> 'xxxxController'. Make sure that the controller has a parameterless
//> public constructor.
//Reason::Basically, what happened is that you didn't register your controllers explicitly in your container.
//Windsor tries to resolve unregistered concrete types for you, but because it can't resolve it (caused by an error in your configuration), it return null.
//It is forced to return null, because Web API forces it to do so due to the IDependencyResolver contract.
//Since Windsor returns null, Web API will try to create the controller itself, but since it doesn't have a default constructor it will throw the "Make sure that the controller has a parameterless public constructor" exception.
//This exception message is misleading and doesn't explain the real cause.
container.Register(Classes.FromThisAssembly()
.BasedOn<IHttpController>()
.LifestylePerWebRequest());***
container.Register(
Component.For<IWatch>().ImplementedBy<Watch>()
);
}
}
Finally, we need to replace the default dependency resolver with the Windsor implementation in Global.asax.cs (Application_Start method) and install our dependencies:
private static IWindsorContainer _container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureWindsor(GlobalConfiguration.Configuration);
}
public static void ConfigureWindsor(HttpConfiguration configuration)
{
_container = new WindsorContainer();
_container.Install(FromAssembly.This());
_container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
var dependencyResolver = new WindsorDependencyResolver(_container);
configuration.DependencyResolver = dependencyResolver;
}

Read Mark Seemann post about windsor plumbing for webapi.

I didn't work directly with Castle Windsor, but I believe the logic should be similar:
Your WatchController ctor should look like this:
public WatchController(IWatch watch)
{
_watch = watch;
}
And this is where you inject the dependency.
You should have the equivalent to a Locator in which you register your WatchController class, and tell it which watch it should receive depending on whatever you want ... design/runtime , day of the week, random number ... whatever works or whatever you need...
The following code is from MVVM-Light, but should clarify the above paragraph:
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
// This will run in design mode, so all your VS design data will come from here
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
// This will run REAL stuff, in runtime
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
// You register your classes, so the framework can do the injection for you
SimpleIoc.Default.Register<MainViewModel>();
...
}

Related

What is the purpose of IServiceProvider.GetService(Type serviceType)?

I am implementing a new .NET Core project and working on dependency injection for my service layer. I created an interface that implements IServiceProvider and now must implement GetService(Type serviceType). This is my interface.
public interface INewsService : IServiceProvider
{
IEnumerable<string> GetAllSources();
}
public class NewsService : INewsService
{
private readonly INewsRepository _newsRepository;
public NewsService(INewsRepository newsRepository)
{
_newsRepository = newsRepository;
}
public IEnumerable<string> GetAllSources()
{
return _newsRepository.GetAllSources();
}
public object GetService(Type serviceType)
{
throw new NotImplementedException();
}
}
What is the purpose of the method? Reading through the MSDN documentation, it's really vague and doesn't clear it up too much. My code runs when I start it...so I'm not sure what it is needed for.
Gets the service object of the specified type.
You should not implement IServiceProvider on INewsService interface.
IServiceProvider desribes factory to create instances of your services:
IServiceProvider provider = GetServiceProvider();
var newsService = provider.GetService(typeof(INewsService));
Read more about service provider: IServiceProvider in ASP.NET Core
IServiceProvider is the interface that implements the Microsoft.Extensions.DependencyInjection. In general, it is for internal use by ASP.NET Core.
What you are supposed to do is implement your own service interfaces:
public interface ISomething
{
void DoSomething();
}
Then build your own concrete types:
public class Something : ISomething
{
public void DoSomething()
{
// Implementation
}
}
You would then register it with the DI container like:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<ISomething, Something>();
}
And you can use your service throughout ASP.NET Core by accepting it as a parameter in a constructor. For example, here is how you would use it in HomeController:
public class HomeController : Controller
{
private readonly ISomething something;
public HomeController(ISomething something)
{
this.something = something ?? throw new ArgumentNullException(nameof(something));
}
public IActionResult Index()
{
something.DoSomething();
return View();
}
}
IServiceProvider.GetService(Type) is called internally when the constructor argument is resolved to get your service from the container (when HomeController is instantiated in this example). It is not required to implement IServiceProvider to use dependency injection with ASP.NET Core, you would only implement it if you wanted to provide some custom functionality that the DI container doesn't already have.
I advise you to look at this answer :GetService()
If you have many services come to the controller
private readonly IMarkService _markService;
private readonly IModelService _modelService;
private readonly IModificationService _modificationService;
public CatalogController(IServiceProvider serviceProvider)
{
_markService = serviceProvider.GetService<IMarkService>();
_modelService = serviceProvider.GetService<IModelService>();
_modificationService = serviceProvider.GetService<IModificationService>();
}

Fail to initialize dependencies. Singleton class using Dependency Injection (Ninject)

I want a singleton class that uses dependency injection (ninject) start as soon as the application starts. The singleton class resides in Domain layer(Class Library) -
Domain.Concrete.Operations. And I'm using this class in WebUI layer(MVC).
I'm stuck at initializing dependencies in static constructor of the service that I plan to start in Application_Start method. What is the right way to do it?
Singleton class:
namespace Domain.Concrete.Operations
{
public sealed class SingletonClass
{
private IInterface1 _iInterface1;
private IInterface2 _iInterface2;
public SingletonClass(IInterface1 iInterface1, IInterface2 iInterface2)
{
this._iInterface1 = iInterface1;
this._iInterface2 = iInterface2;
StartAllOperations();
}
public void StartAllOperations()
{
}
}
}
NinjectDependencyResolver:
namespace WebUI.Infrastructure
{
public class NinjectDependencyResolver : IDependencyResolver
{
IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
kernel.Bind<IInterface1>().To<Class1>();
kernel.Bind<IInterface2>().To<Class2>();
kernel.Bind<SingletonClass>().To<SingletonClass>().InSingletonScope();
}
}
}
As far as I understand this code will help to return the same instance of SigletonClass:
kernel.Bind<SingletonClass>().To<SingletonClass>().InSingletonScope();
Service in App_Start:
namespace WebUI.App_Start
{
public class OperationManagerService
{
private IInterface1 _iInterface1;
private IInterface2 _iInterface2;
static OperationManagerService() //static constructor cannot have parameters
{
_iInterface1 = //how to initialize
_iInterface2 = //interfaces here?
}
public static void RegisterService()
{
new SingletonClass(_iInterface1, _iInterface2);
}
}
}
Register service in Application_Start (Global.asax.cs):
namespace WebUI
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
OperationManagerService.RegisterService();
}
}
}
UPDATE:
I must admit that I'm able to initialize dependencies like this, but then I can only use the OperationManagerService class in controller. Not in Application_Start!
static OperationManagerService(IInterface1 iInterface1, IInterface2 iInterface2)
{
_iInterface1 = iInterface1;
_iInterface2 = iInterface2;
}
This leads me to thought that I can't use injection with Ninject in Application_Start. If it's true, then where is the right place to create a class that should load at startup?
You are trying to intermix the Singleton pattern with Ninject's Singleton Scope, which confuses who is trying to construct what when. Don't use the old the Singleton pattern when trying to use DI. Half of the point of DI is to manage the lifetime (scope) of the objects it contains. You do this by specifying .InSingletonScope() as you have done.
Now, onto your question of injecting dependencies into a startup feature: you will need to allow Ninject to construct the OperationManagerService in order to have the dependencies provided by Ninject. To do this, register it in Singleton scope, as you did with SingletonClass. The first time it is requested from the Ninject container, it will be constructed and injected with the necessary parameters. Singleton scope only tells Ninject to only ever construct one instance.
However, it seems that you would like it to be constructed during startup? If this is a requirement, something will need to ask for it. The simplest solution would be to get it after binding it:
private void AddBindings()
{
kernel.Bind<IInterface1>().To<Class1>();
kernel.Bind<IInterface2>().To<Class2>();
kernel.Bind<SingletonClass>().ToSelf().InSingletonScope();
kernel.Bind<OperationManagerService>().ToSelf().InSingletonScope();
kernel.Get<OperationManagerService>(); // activate
}
If you find yourself doing this alot, I have used a simple "auto-start" pattern:
public interface IAutoStart()
{
void Start();
}
public class SomeClassThatStarts : IAutoStart
{
public void Start()
{
Console.Log("Starting!");
}
}
public class AutoStartModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
foreach(var starter in Kernel.GetAll<IAutoStart>())
{
starter.Start();
}
}
}
Register the AutoStartModule last in your Kernel, and any IAutoStart will be loaded with any dependencies and started.

Way to dynamically get repositories without a dependency on a DI container

I have a class that returns a repository (read only) using a generic method this is to reduce the number of repository classes I need to inject into classes in my business layer. It also allows me to add and use a new repo anywhere I have this wrapper class simply by adding a repo which implements IGenericReadRepo<T> as this will be registered in unity using the line Container.RegisterType(typeof(IGenericReadRepository<>), typeof(GenericReadRepository<>), new TransientLifetimeManager());. However this has is dependent on unity being the DI container. This smells to me.
public class ReadRepositoryWrapper : IReadRepositoryWrapper
{
private IUnityContainer _unityContainer;
public ReadRepositoryWrapper(IUnityContainer container)
{
_unityContainer = container;
}
public IGenericReadRepository<T> GetReadRepository<T>() where T : class
{
return _unityContainer.Resolve<IGenericReadRepository<T>>();
}
}
Can anyone think of a way to implement the GetReadRepository<T> without a the dependency on unity while not introducing any new dependencies. Or can someone think of another way to get repositories without having bloated constructors or a dependency on my context.
You can create generic factory interfaces/classes for dynamic object creation. Many DI containers support object creation using lambda expressions.
public interface IFactory<T>
{
T Create();
}
public class Factory<T> : IFactory<T>
{
private readonly Func<T> _creator;
public Factory(Func<T> creator)
{
if(creator == null)
throw new ArgumentNullException("creator");
_creator = creator;
}
public T Create()
{
return _creator();
}
}
The generic factory interface than can be injected into the consuming classes.
public class ReadRepositoryWrapper<T> : IReadRepositoryWrapper<T> where T : class
{
private readonly IFactory<IGenericReadRepository<T>> _factory;
public ReadRepositoryWrapper(IFactory<IGenericReadRepository<T>> factory)
{
if(factory == null)
throw new ArgumentNullException("factory");
_factory = factory;
}
public IGenericReadRepository<T> GetReadRepository()
{
return _factory.Create();
}
}
Or something like that.

Unity and IoC is not working

I'm trying to implement a demo application to understand Unity and IoC. But I'm kind of struck.
I'm having error:
An error occurred when trying to create a controller of type
'ProductController'. Make sure that the controller has a parameterless
public constructor.
Here is the brief overview of what I'm doing:
I have five projects:
Data Model
Business Services
WebApi
Business Entities
Resolver
I'm following this code project tutorial:
https://www.codeproject.com/articles/997216/restful-day-sharp-resolve-dependency-of-dependenci
I've completed Day 3. but I'm not able to resolve the issue.
Here is my WebApi Project Unity RegisterTypes function.
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
//container.RegisterType<IProductServices, ProductServices>();
//Component initialization via MEF
ComponentLoader.LoadContainer(container, ".\\bin", "WebApi.dll");
ComponentLoader.LoadContainer(container, ".\\bin", "BusinessServices.dll");
}
Here is ProductController Constructor
public class ProductController : ApiController
{
private readonly IProductServices _productServices;
#region Public Constructor
/// <summary>
/// Public constructor to initialize product service instance
/// </summary>
public ProductController(IProductServices productServices)
{
_productServices = productServices;
}
#endregion
BusinessServices project is registering the dependencies in a DependencyResolver class
using Resolver;
using System.ComponentModel.Composition;
namespace BusinessServices
{
[Export(typeof(IComponent))]
public class DependencyResolver : IComponent
{
public void SetUp(IRegisterComponent registerComponent)
{
registerComponent.RegisterType<IProductServices, ProductServices>();
}
}
}
Can anybody help me?
Thanks!
You need to register needed types:
container.RegisterType<ProductController>();
container.RegisterType<IProductServices, ProductServices>();
given that you've implemented IDependencyResolver.GetService using your Unity container, for example:
public object GetService(Type serviceType)
{
if(container.IsRegistered(serviceType))
{
return container.Resolve(serviceType);
}
return null;
}
a simple demo can be done like this:
public class UnityResolver : IDependencyResolver
{
public IUnityContainer _container;
public UnityResolver()
{
_container = new UnityContainer();
RegisterTypes(_container);
}
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
if(_container.IsRegistered(serviceType))
{
return _container.Resolve(serviceType);
}
return null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return Enumerable.Empty<object>();
}
public void Dispose()
{
}
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
container.RegisterType<ProductController>();
container.RegisterType<IProductServices, ProductServices>();
//Component initialization via MEF
//ComponentLoader.LoadContainer(container, ".\\bin", "WebApi.dll");
//ComponentLoader.LoadContainer(container, ".\\bin", "BusinessServices.dll");
}
}
and set the resolver in Application_Start:
GlobalConfiguration.DependencyResolver = new UnityResolver();

can't get Unity3 and SignalR 2.0 work together

I try to implement SignalR 2.0 together with Unity3 but so far without success and without exceptions or errors. Also breakpoints doesn't get hit so it is really hard to debug and to figure out what I am doing wrong.
I took this webpage as example:
http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection
but with ninject replaced with unity.
This is my code.
I got a startUp class:
[assembly: OwinStartup(typeof(Hubs.StartUp))]
namespace Hubs
{
public class StartUp
{
public void Configuration(IAppBuilder app)
{
var configuration = new HubConfiguration //I put a breakpoint here
{
Resolver = GetResolver()
};
app.MapSignalR(configuration);
}
private static IDependencyResolver GetResolver()
{
var container = new UnityContainer(); //I put a breakpoint here
Validations.IoC.Initialize(container);
return new UnityDependencyResolver(container);
}
}
}
The UnityDependencyResolver class:
namespace Hubs
{
public class UnityDependencyResolver : DefaultDependencyResolver
{
private readonly IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
return _container.Resolve(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return _container.ResolveAll(serviceType) ?? base.GetServices(serviceType);
}
}
}
A hub class using constructor dependency injection
namespace Hubs.Hubs
{
public class TestHub : Hub
{
private readonly ISomeValidation _validation;
public TestHub(ISomeValidation validation)
{
_validation = validation;
}
public SomeObject Get()
{
return _validation.Get();
}
}
}
And the Validations.IoC class
public static class IoC
{
public static void Initialize(UnityContainer container)
{
container.RegisterType<ISomeValidation, SomeValidation>();
}
}
I can't figure out what I am doing wrong, so can someone help me to figure that out?
After some more searching, I think I might find the cause of the problem. It seems there is a default dependency resolver that tries to resolve the hub class but fails to do it, which makes sense cause I don't register the hub class.
I believe that in the ninject example the registering happens in this code part:
kernel.Bind<IHubConnectionContext>().ToMethod(context =>
resolver.Resolve<IConnectionManager>().GetHubContext<StockTickerHub>().Clients
).WhenInjectedInto<IStockTicker>();
Not sure though as I have never done anything with ninject. I couldn't figure out how to translate this to Unity code.
After some more searching I found another code example here: http://damienbod.wordpress.com/2013/11/05/using-signalr-with-unity/
And that is actually working. It contains also the registering of the hub classtypes and therefor it is probably the solution of my problem.

Categories

Resources