Does ninject works for static property bindings?
I set IEventHandlerFactory with Ninject,
public class ServiceModule: NinjectModule
{
public override void Load()
{
Kernel.Bind<IEventHandlerFactory>().To<EventHandlerFactoryService>();
}
}
And my static class
public static class DomainEvents
{
public static IEventHandlerFactory EventHandlerFactory { get; set; }
public static void Raise<T>(T domainEvent)
{
EventHandlerFactory
.GetDomainEventHandlersFor(event)
.ForEach(h => h.Handle(event));
}
}
But this does not bind to static property.
DomainEvents.EventHandlerFactory is Null
Is there any way to bind property?
Since ninject doesn't have a concept of dividing "creating all bindings" and "using the kernel", there's of course no extension point for "tell me when the kernel is done with all bindings so i can do something".
With a static class it also doesn't make sense to request it from the kernel.
So the obvious answer is: no.
Of course, the obvious solution is just to extend your code where you're done building up the kernel (probably close to where you do var kernel = new StandardKernel()) with a call like
DomainEvents.EventHandlerFactory = kernel.Get<IEventHandlerFactory>();
Alternative 1 - tying initialization to activation of another type
If that initialization should be tied to the activation of another type, let's say IFoo, you can also do:
kernel.Bind<IFoo>()
.To<Foo>()
.InSingletonScope()
.OnActivation(x =>
DomainEvents.EventHandlerFactory = kernel.Get<IEventHandlerFactory>());
Alternative 2 - tying initialization to loading of a NinjectModule
You can sublcass NinjectModule and in it's Load you can initialize the static property. This works in case you can make sure the module is only loaded after the kernel is sufficiently initialized to create an IEventHandlerFactory.
Disclaimer
Both alternatives probably suck because their not clear and not straight forward. They hide a dependency deep in some place. I'd only use one of these if the first approach is not feasible, for example because your writing a plugin and there's no extension point post-kernel initialization.
Do you really need DomainEvents class to be static?
Maybe you can do as follows. Raise will still be static though.
You will have to call kernel.Get though.
public class DomainEvents
{
public static IEventHandlerFactory EventHandlerFactory { get; set; }
public DomainEvents(IEventHandlerFactory factory)
{
EventHandlerFactory = factory;
}
public static void Raise<T>(T domainEvent)
{
EventHandlerFactory
.GetDomainEventHandlersFor(event)
.ForEach(h => h.Handle(event));
}
}
Related
Im trying to figure out how to dynamically instantiate class when it's first used. Something like autofac's Lazy does but without refactoring all my classes.
Is there any possiblity to do something like this:
public class MyService : IMyService {
public MyService() {
// I want it to be invoked only if SomeMethod was invoked before.
// 1. Attempt to invoke SomeMethod
// 2. call MyService.constructor
// 3. invoke MyService.SomeMethod()
}
public void SomeMethod() {
///literally any code.
}
}
It has to be done without changing existing codebase (except services registration/ autofac setup or other areas that could be changed without much effort), and all services look's like that:
public class Service : IService {
public Service(AnotherService service){
///...
}
}
My initial idea was to create Proxy class and then while registering services wrap it with that proxy.
It could look something like this:
public class Proxy<T>
{
private T _target;
private bool instantiated = false;
private void Instantiate()
{
Console.WriteLine("Creating instance");
_target = Activator.CreateInstance<T>();
}
public void xxx() - this method should be called every time any wrapped type method get's called.
{
if (instantiated == false)
{
Instantiate();
instantiated = true;
}
/// proceed with invocation. (im not sure how to do this via reflection).
}
}
The main issue with this idea is that above proxy class should be created at runtime via reflection and it has to mimic wrapping class behaviour.
I'd appreciate any advice on how to approach this problem.
All i want to lazy create dependencies in autofac container (currently if dependency A is requiring dependency B then B is instantiated, i want change this to instantiate B only if any method from A calls B.method).
Thanks!
What you're looking for is the Proxy pattern. You can create a lazy proxy as follows:
public class LazyMyServiceProxy : IMyService
{
private readonly Lazy<MyService> lazy;
public LazyMyServiceProxy(Lazy<MyService> lazy) => this.lazy = lazy;
public void SomeMethod() => this.lazy.SomeMethod();
}
You can use this proxy using the following Autofac registrations.
builder.RegisterType<MyService>();
builder.RegisterType<LazyMyServiceProxy>().As<IMyService>();
I need an architectural advice.
I have two classes:
public class Shell
{
public IPage CurrentPage { get; set; }
public void ChangePage(IPage page)
{
CurrentPage = page;
}
}
public class SomeFunctionallityClass
{
private readonly Shell _shell;
private readonly IPage _somePage;
public Model1(Shell shell, IPage page)
{
_shell = shell;
_somePage = page;
}
public void MakeSomeCrazyStuff()
{
_shell.ChangePage(_somePage);
}
}
In Shell class i have a CurrentPage property and this is the property which very many classes in the application want to have access to.
Right now i pass Shell object to the classes which need to change the page.
But what will be the best way to give access to the same class for many other classes?
Actually your solution of passing the Shell class to each other class that requires it, is not too bad, especially if you do it via the constructor.
Sure, the most common ways to do this are using the Singleton or a class with static methods. But if you are honest, in this context both of them are nothing but masked global state.
The original purpose of the singleton is to make sure only one object of a class exists, not to make something easily accessible. However the latter is the most common reason why developers use it. Other people therefore call it the "King of Antipatterns" :)
To be honest, I use both the Singleton and static methods myself in some cases to make my life easier (in the short term). But I never feel good about it.
To summarize, as far as I know you have three basic options:
Pass object in constructor
Singleton
Static methods
All of these have their pros and cons, but I consider the first solution the cleanest because it does not introduce global state.
You might want consider using Singleton design pattern:
https://msdn.microsoft.com/en-us/library/ff650316.aspx
Choose the one that fully answers your requirements.
You can make your Shell static:
public static class Shell
{
private static IPage CurrentPage { get; set; }
public static void SetCurrentPage(IPage page)
{
CurrentPage = page;
}
}
public class SomeOtherClass
{
public vod ShowShellPropery()
{
MessageBox.Show(Shell.Property);
}
}
Also having a setter ChangePage, you should make your CurrentPage private. Otherwise, you have two ways of changing your current page: with the setter ChangePage(page), and with CurrentPage = page, which is not good. Also I renamed your setter ChangePage to SetCurrentPage, so now it is clear that it is a setter
I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)
I'm trying to implement DI in a class, but I'm not sure that my design is appropriate.
The relevent code in the class I want to add DI to
class DoerValidation
{
public DoerValidation()
{
compileData();
}
private void compileData()
{
doersActive = Doer.GetActiveDoers();
//...
}
}
And in my Doer class
public partial class Doer
{
private static readonly DoerRepository repository = new DoerRepository();
public static IEnumerable<Doer> GetActiveDoers()
{
return repository.Doers.Where(c => c.Person.IsActive);
}
}
I just don't get how I could implement DI in this situation. Maybe the GetActiveDoers method is bad design? Where would you put this method otherwise?
Would it be a good practice to start adding new methods directly in the repository? Some people told me it should stay clean so it implements only this
public interface IDoerRepository
{
IQueryable<Doer> Doers { get; }
void SaveDoer(Doer doer);
void DeleteDoer(Doer doer);
}
It sounds like you need to inject the DoerRepository into DoerValidation basically - pass it into the constructor.
Both the GetActiveDoers and the static variable go against the principles of DI, IMO.
Static methods and properties are procedural in nature. If you expose your GetActiveDoers() method statically, there is no way to inject its functionality -- clients can only ignore it or use it inline wherever it's needed.
If you're committed to DI and to a static implementation, you need to write an instance wrapper for that static class and inject the instance wrapper.
here's my situation:
I have an application that generates stuff based on templates (using T4) and i have multiple templates class that inherit from an ITemplate interface.
What i wanna do in my Main is to dinamically inject some ITemplate implementations in my Generator class, what implementation to use being read from a, let's say, configuration file. Then in the Main i should call the Generator that will understand what template to use and call the proper TransformText().
I'm using Ninject.
It's the first time i use Dependency Injection in a statically typed language, so I'm not sure on how to proceed...
Regards,
Hugo
If you are truly want to use DI here a simple example, but if you are searching something like plugin system you might wanna check out mef.
Lets assume you have a generator
public class Generator
{
private ITemplate _template;
public Generator(ITemplate t)
{
_template = t;
}
public void Generate()
{
_template.Generate();
}
}
Setup your Modules.
public class MyNinjectModules : NinjectModule
{
public override void Load()
{
Bind<ITemplate>().To< TemplateImplementation>();
Bind<Generator>().ToSelf();
}
}
then prepare your Ninject Kernel, and use it.
public class Program
{
public static void Main(
{
var kernel = new StandardKernel(MyNinjectModules);
var myGenerator = kernel.Get<Generator>();
}
}