Ok, I am officially losing my mind over this ...
I am trying to create a Castle.Windsor interceptor, but resolving from the container keeps throwing this exception:
DependencyResolverException: An interceptor registered for
DI_Test.DatabaseService doesn't implement the IInterceptor interface
As far as I can see I have done everything by the book, and the container contents (in debug-mode) doesn't report any mal-configured services.
Configuration of the container:
public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container
.Register(Component.For<Runner>())
.Register(Component.For<IDataDependency>()
.ImplementedBy<DatabaseService>()
.LifestyleSingleton()
.Interceptors(InterceptorReference.ForKey("wait")).Anywhere)
.Register(Component.For<WaitAndRetryInterceptor>().LifeStyle.Singleton
.Named("wait"))
;
}
}
My interceptor:
public class WaitAndRetryInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//throw new NotImplementedException();
}
}
My program:
public class Runner
{
public void Run()
{
_dataDependency.GetData();
}
public Runner(IDataDependency dataDependency)
{
_dataDependency = dataDependency;
}
private readonly IDataDependency _dataDependency;
}
public interface IDataDependency
{
void GetData();
}
public class DatabaseService : IDataDependency
{
public void GetData()
{
throw new NotImplementedException();
}
}
The program works perfectly without the configuration of the interceptor.
What I cannot figure out is WHY it throws this exception. The interceptor is clearly implementing the IInterceptor interface ... so what is the problem?
Thanks :-)
There are two interfaces named IInterceptor
Castle.DynamicProxy.IInterceptor
Castle.Core.Interceptor.IInterceptor
Not sure what is the difference between them, but to get it working you must use the first one.
Related
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.
I'm trying to implement IoC in my windows form application. My choice fell on Simple Injector, because it's fast and lightweight. I also implement unit of work and repository pattern in my apps. Here is the structure:
DbContext:
public class MemberContext : DbContext
{
public MemberContext()
: base("Name=MemberContext")
{ }
public DbSet<Member> Members { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();\
}
}
Model:
public class Member
{
public int MemberID { get; set; }
public string Name { get; set; }
}
GenericRepository:
public abstract class GenericRepository<TEntity> : IGenericRepository<TEntity>
where TEntity : class
{
internal DbContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
}
MemberRepository:
public class MemberRepository : GenericRepository<Member>, IMemberRepository
{
public MemberRepository(DbContext context)
: base(context)
{ }
}
UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
public DbContext context;
public UnitOfWork(DbContext context)
{
this.context = context;
}
public void SaveChanges()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
MemberService:
public class MemberService : IMemberService
{
private readonly IUnitOfWork unitOfWork;
private readonly IMemberRepository memberRepository;
public MemberService(IUnitOfWork unitOfWork, IMemberRepository memberRepository)
{
this.unitOfWork = unitOfWork;
this.memberRepository = memberRepository;
}
public void Save(Member member)
{
Save(new List<Member> { member });
}
public void Save(List<Member> members)
{
members.ForEach(m =>
{
if (m.MemberID == default(int))
{
memberRepository.Insert(m);
}
});
unitOfWork.SaveChanges();
}
}
In Member Form I only add a textbox to input member name and a button to save to database. This is the code in member form:
frmMember:
public partial class frmMember : Form
{
private readonly IMemberService memberService;
public frmMember(IMemberService memberService)
{
InitializeComponent();
this.memberService = memberService;
}
private void btnSave_Click(object sender, EventArgs e)
{
Member member = new Member();
member.Name = txtName.Text;
memberService.Save(member);
}
}
I implement the SimpleInjector (refer to http://simpleinjector.readthedocs.org/en/latest/windowsformsintegration.html) in Program.cs as seen in the code below:
static class Program
{
private static Container container;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Bootstrap();
Application.Run(new frmMember((MemberService)container.GetInstance(typeof(IMemberService))));
}
private static void Bootstrap()
{
container = new Container();
container.RegisterSingle<IMemberRepository, MemberRepository>();
container.Register<IMemberService, MemberService>();
container.Register<DbContext, MemberContext>();
container.Register<IUnitOfWork, UnitOfWork>();
container.Verify();
}
}
When I run the program and add a member, it doesn't save to database. If I changed container.Register to container.RegisterSingle, it will save to database. From the documentation, RegisterSingle will make my class to be a Singleton. I can't using RegisterLifeTimeScope because it will generate an error
"The registered delegate for type IMemberService threw an exception. The IUnitOfWork is registered as 'Lifetime Scope' lifestyle, but the instance is requested outside the context of a Lifetime Scope"
1) How to use SimpleInjector in Windows Form with UnitOfWork & Repository pattern?
2) Do I implement the patterns correctly?
The problem you have is the difference in lifestyles between your service, repository, unitofwork and dbcontext.
Because the MemberRepository has a Singleton lifestyle, Simple Injector will create one instance which will be reused for the duration of the application, which could be days, even weeks or months with a WinForms application. The direct consequence from registering the MemberRepository as Singleton is that all dependencies of this class will become Singletons as well, no matter what lifestyle is used in the registration. This is a common problem called Captive Dependency.
As a side note: The diagnostic services of Simple Injector are able to spot this configuration mistake and will show/throw a Potential Lifestyle Mismatch warning.
So the MemberRepository is Singleton and has one and the same DbContext throughout the application lifetime. But the UnitOfWork, which has a dependency also on DbContext will receive a different instance of the DbContext, because the registration for DbContext is Transient. This context will, in your example, never save the newly created Member because this DbContext does not have any newly created Member, the member is created in a different DbContext.
When you change the registration of DbContext to RegisterSingleton it will start working, because now every service, class or whatever depending on DbContext will get the same instance.
But this is certainly not the solution because having one DbContext for the lifetime of the application will get you into trouble, as you probably already know. This is explained in great detail in this post.
The solution you need is using a Scoped instance of the DbContext, which you already tried. You are missing some information on how to use the lifetime scope feature of Simple Injector (and most of the other containers out there). When using a Scoped lifestyle there must be an active scope as the exception message clearly states. Starting a lifetime scope is pretty simple:
using (ThreadScopedLifestyle.BeginScope(container))
{
// all instances resolved within this scope
// with a ThreadScopedLifestyleLifestyle
// will be the same instance
}
You can read in detail here.
Changing the registrations to:
var container = new Container();
container.Options.DefaultScopedLifestyle = new ThreadScopedLifestyle();
container.Register<IMemberRepository, MemberRepository>(Lifestyle.Scoped);
container.Register<IMemberService, MemberService>(Lifestyle.Scoped);
container.Register<DbContext, MemberContext>(Lifestyle.Scoped);
container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
and changing the code from btnSaveClick() to:
private void btnSave_Click(object sender, EventArgs e)
{
Member member = new Member();
member.Name = txtName.Text;
using (ThreadScopedLifestyle.BeginScope(container))
{
var memberService = container.GetInstance<IMemberService>();
memberService.Save(member);
}
}
is basically what you need.
But we have now introduced a new problem. We are now using the Service Locator anti pattern to get a Scoped instance of the IMemberService implementation. Therefore we need some infrastructural object which will handle this for us as a Cross-Cutting Concern in the application. A Decorator is a perfect way to implement this. See also here. This will look like:
public class ThreadScopedMemberServiceDecorator : IMemberService
{
private readonly Func<IMemberService> decorateeFactory;
private readonly Container container;
public ThreadScopedMemberServiceDecorator(Func<IMemberService> decorateeFactory,
Container container)
{
this.decorateeFactory = decorateeFactory;
this.container = container;
}
public void Save(List<Member> members)
{
using (ThreadScopedLifestyle.BeginScope(container))
{
IMemberService service = this.decorateeFactory.Invoke();
service.Save(members);
}
}
}
You now register this as a (Singleton) Decorator in the Simple Injector Container like this:
container.RegisterDecorator(
typeof(IMemberService),
typeof(ThreadScopedMemberServiceDecorator),
Lifestyle.Singleton);
The container will provide a class which depends on IMemberService with this ThreadScopedMemberServiceDecorator. In this the container will inject a Func<IMemberService> which, when invoked, will return an instance from the container using the configured lifestyle.
Adding this Decorator (and its registration) and changing the lifestyles will fix the issue from your example.
I expect however that your application will in the end have an IMemberService, IUserService, ICustomerService, etc... So you need a decorator for each and every IXXXService, not very DRY if you ask me. If all services will implement Save(List<T> items) you could consider creating an open generic interface:
public interface IService<T>
{
void Save(List<T> items);
}
public class MemberService : IService<Member>
{
// same code as before
}
You register all implementations in one line using Batch-Registration:
container.Register(typeof(IService<>),
new[] { Assembly.GetExecutingAssembly() },
Lifestyle.Scoped);
And you can wrap all these instances into a single open generic implementation of the above mentioned ThreadScopedServiceDecorator.
It would IMO even be better to use the command / handler pattern (you should really read the link!) for this type of work. In very short: In this pattern every use case is translated to a message object (a command) which is handled by a single command handler, which can be decorated by e.g. a SaveChangesCommandHandlerDecorator and a ThreadScopedCommandHandlerDecorator and LoggingDecorator and so on.
Your example would then look like:
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
public class CreateMemberCommand
{
public string MemberName { get; set; }
}
With the following handlers:
public class CreateMemberCommandHandler : ICommandHandler<CreateMemberCommand>
{
//notice that the need for MemberRepository is zero IMO
private readonly IGenericRepository<Member> memberRepository;
public CreateMemberCommandHandler(IGenericRepository<Member> memberRepository)
{
this.memberRepository = memberRepository;
}
public void Handle(CreateMemberCommand command)
{
var member = new Member { Name = command.MemberName };
this.memberRepository.Insert(member);
}
}
public class SaveChangesCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
{
private ICommandHandler<TCommand> decoratee;
private DbContext db;
public SaveChangesCommandHandlerDecorator(
ICommandHandler<TCommand> decoratee, DbContext db)
{
this.decoratee = decoratee;
this.db = db;
}
public void Handle(TCommand command)
{
this.decoratee.Handle(command);
this.db.SaveChanges();
}
}
And the form can now depend on ICommandHandler<T>:
public partial class frmMember : Form
{
private readonly ICommandHandler<CreateMemberCommand> commandHandler;
public frmMember(ICommandHandler<CreateMemberCommand> commandHandler)
{
InitializeComponent();
this.commandHandler = commandHandler;
}
private void btnSave_Click(object sender, EventArgs e)
{
this.commandHandler.Handle(
new CreateMemberCommand { MemberName = txtName.Text });
}
}
This can all be registered as follows:
container.Register(typeof(IGenericRepository<>),
typeof(GenericRepository<>));
container.Register(typeof(ICommandHandler<>),
new[] { Assembly.GetExecutingAssembly() });
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(SaveChangesCommandHandlerDecorator<>));
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(ThreadScopedCommandHandlerDecorator<>),
Lifestyle.Singleton);
This design will remove the need for UnitOfWork and a (specific) service completely.
I am brand new to MEF and am stuck in "No parameterless constructor defined for this object" hell. I've looked at a lot of posts etc. over the last many hours and am totally stuck. What am I doing wrong? I'm using .NET 4.5, so do I still need all these attributes? Am I mixing older style MEF in with newer?
UPDATE:
The solution I'm working on also references Unity 3.3, so I think they may be stepping on each other. Do I need to remove Unity?
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller
{
private readonly IHomeService _service;
[ImportingConstructor]
public HomeController(IHomeService service)
{
_service = service;
}
}
[Export(typeof(IHomeService))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeService : IHomeService
{
private readonly IServiceSearch _serviceSearch;
[ImportingConstructor]
public HomeService(IServiceSearch serviceSearch)
{
_serviceSearch = serviceSearch;
}
}
[InheritedExport]
public interface IHomeService
{
// ...
}
[Export(typeof(IServiceSearch))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ServiceSearch : DataHub.Search, IServiceSearch
{
[ImportingConstructor]
public ServiceSearch(IMapper<xxx, xxxDTO> x)
{
// ...
}
[InheritedExport]
public interface IMapper<TDomain,TDto>
{
TDomain ToDomain(object o);
void Initialize();
TDto DomainToDto(TDomain domain);
}
[Export(typeof(IMapper<Account, AccountDTO>))]
public class AccountMapper : IMapper<Account, AccountDTO>
{
//....
}
protected void Application_OnStart()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var composition = new CompositionContainer(catalog);
IControllerFactory mefControllerFactory = new MefControllerFactory(composition); //Get Factory to be used
ControllerBuilder.Current.SetControllerFactory(mefControllerFactory);
}
public class MefControllerFactory : DefaultControllerFactory
{
private readonly CompositionContainer _container;
public MefControllerFactory(CompositionContainer container)
{
_container = container;
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
Lazy<object, object> export = _container.GetExports(controllerType, null, null).FirstOrDefault();
return null == export
? base.GetControllerInstance(requestContext, controllerType)
: (IController)export.Value;
}
public override void ReleaseController(IController controller)
{
((IDisposable)controller).Dispose();
}
}
I managed to get your code working with these modifications:
Move the types nested inside ServiceSearch outside of it. I don't think that MEF supports nested types. (Looks as though this is just a typo in the code sample above. I don't think it was intended.)
Remove the InheritedExportAttribute from IMapper<,>. You have an explicit export on AccountMapper anyway. Without making this change, you end up with AccountMapper being exported twice. The import into ServiceSearch's constructor then fails because MEF doesn't know which of the two matching exports to use. Alternatively keep the InheritedExportAttribute and remove the explicit export.
Either remove the InheritedExportAttribute on IHomeService or the ExportAttribute on HomeService, for the same reason as above.
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.
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>();
...
}