i actually want to call my 'DoSomething()' method when umbraco starts up (in the real project it's setting up a bunch of examine index stuff).
so the question is, how do i inject the 'IMyService' into my 'UmbracoBooter' class? if i try this:
private readonly IMyService _myService;
public Startup(IMyService myService)
{
_myService = myService;
}
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var kernel = new StandardKernel();
kernel.Bind<IMyService>().To<MyService>();
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
_myService.DoSomething();
}
then '_myService' is always null...
i've tried everything i can think off and just can't get this to work... it feels like i need to inject and call the method further down the pipe maybe?
has anyone done this kinda thing before or am i attempting to do something that i shouldn't?!
thank you so much for the reply, really appreciate it ;)
i see where you're going, moving the code in '_myService.DoSomething();' into the startup class would be ideal however (and you knew there'd be a however...) the implementation of the 'IMyService' interface (yup, you guessed it!) calls a method in another interface:
public class MyService : IMyService
{
private readonly ILog _log;
public MyService(ILog log)
{
_log = log;
}
public void DoSomething()
{
_log.Info(DateTime.Now);
}
}
the trick being if i move this code into the startup i have to inject 'ILog' and i'm back to it being null... damn.
so i investigated the static class idea and i think i've got something working...
my startup class now has this:
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var kernel = new StandardKernel();
kernel.Bind<ILog>().ToMethod(context => LogManager.GetLogger(context.Request.Target.Member.DeclaringType));
kernel.Bind<IMyService>().To<MyService>();
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
Bootstrapper.Init();
}
the bootstrapper has this:
public static class Bootstrapper
{
private static IMyService MyService => DependencyResolver.Current.GetService<IMyService>();
public static void Init()
{
MyService.DoSomething();
}
}
based on the testing i've done, this is now working! i can't test my startup or boostrapper classes but tbh i couldnt really anyway and realistically there's no logic to test anyway... and it's the code in the implementation of 'IMyService' that has the testable code.
still got a bit of playing to do (like try this in a real project rather than the test project i'm using for this post) but does this sound about right?!
I think I see what your'e doing there, and what you're doing makes sense.
I would personally move the DI setup into another class / method, have another class that has an instance of IMyService in it and call them both from the OnApplication started event handler.
public void OnApplicationStarted (..)
{
BootStrapper.Init(); // DI Setup Code goes in here
StartupTasks.Run(); // (or whatever name suits based on what it's doing) instance of IMyService goes in here
}
This is just a personal preference in terms of separating out different pieces of functionality though.
I hope you get it working nicely in a live project!
ioc/dependency injection issue when umbraco starts up
ok, i've been banging my head against the wall for far too long on this one and i just can't see how to make this work...
i'm using ninject for ioc and it's working using this code:
i can inject 'IMyService' into a controller and it works e.g.
so far so good. however...
i actually want to call my 'DoSomething()' method when umbraco starts up (in the real project it's setting up a bunch of examine index stuff).
so the question is, how do i inject the 'IMyService' into my 'UmbracoBooter' class? if i try this:
then '_myService' is always null...
i've tried everything i can think off and just can't get this to work... it feels like i need to inject and call the method further down the pipe maybe?
has anyone done this kinda thing before or am i attempting to do something that i shouldn't?!
any feedback would be blardy amazing ;)
cheers,
jake
Hi Jake,
You're correct; for this to work you need to create an instance of a class that takes an IMyService parameter in the constructor.
Is the code in _myService.DoSomething(); only ever done at application startup? If that's the case, then I would move it into the Bootstrapper class.
The way I handle startup code is to have a Bootstrapper class with a static function called Init, so the event handler looks something like
and Bootstrapper.Init() has all the code that's needed on application start; setting up IoC, creating custom database tables, setting up indexes, etc
Hope that helps!
Euan
hi euan,
thank you so much for the reply, really appreciate it ;)
i see where you're going, moving the code in '_myService.DoSomething();' into the startup class would be ideal however (and you knew there'd be a however...) the implementation of the 'IMyService' interface (yup, you guessed it!) calls a method in another interface:
the trick being if i move this code into the startup i have to inject 'ILog' and i'm back to it being null... damn.
so i investigated the static class idea and i think i've got something working...
my startup class now has this:
the bootstrapper has this:
based on the testing i've done, this is now working! i can't test my startup or boostrapper classes but tbh i couldnt really anyway and realistically there's no logic to test anyway... and it's the code in the implementation of 'IMyService' that has the testable code.
still got a bit of playing to do (like try this in a real project rather than the test project i'm using for this post) but does this sound about right?!
cheers,
jake
Hi Jake,
I think I see what your'e doing there, and what you're doing makes sense.
I would personally move the DI setup into another class / method, have another class that has an instance of IMyService in it and call them both from the OnApplication started event handler.
This is just a personal preference in terms of separating out different pieces of functionality though.
I hope you get it working nicely in a live project!
Cheers, Euan
is working on a reply...