Executing order of constructor injection and property injection using ninject 2 - module

I'm loading a ninject module in my (WCF) project and want to hook up log4net in my module using a custom provider. The reason I'm using a provider is that the GetLogger method needs to get passed the class in which the Injection is taking place. If this is not the way to do this, please let me know, I'm new to Ninject. (Context.getType() is not correct btw, I'm having some trouble doing this.)
The main problem is that my ILog variables in my classes get Initialized after the constructor has executed, but I want to be able to use the logging in my constructor. I am also using Ninject to call my constructor and bind it's parameters to concrete classes.
Bind<IBroker>().To<Broker>(); // constructor
Bind<ILog>().ToProvider(new log4netILogProvider()) // property
private class log4netILogProvider : Ninject.Activation.Provider<ILog>
{
protected override ILog CreateInstance(IContext context)
{
return LogManager.GetLogger(context.getType());
}
}
All help is appreciated.

No IoC framework will ever be able to do property injection before constructor injection. An IoC framework can only do the same things you can do in a manually written factory. You can't access a property of an object in a factory before it has been created right? So can't the IoC framework.
Basically you have two options.
Do constructor injection (prefered)
Do method injection and execute your constructor code in the method.
[Inject]
public void Initialize(ILog log) { ... }

I would also suggest a third option. You can implement Ninject's IInitializable interface then see if you can't move the code that relies on the property injecttor into your implementation of Initialize(). Ninject guarantess that all constructor injection AND propery injection is finished before Initialize is invoked.

Related

What does Kernel.Inject(instance); actually do?

I am learning to use dependency injection with ninject. Most of the properties and methods are fairly intuitive, one that has me though is Kernel.Inject(instance);
What does the Inject method actually do as it doesn't return anything. I've looked around but search for a method called inject on a dependency injection container is a nightmare, I can't find any references to the method specifically.
Kernel.Inject(instance) will inject dependencies into an already existing object.
That's why it returns void because it takes the parameter object instance and starts to investigate it's methods and property setters looking for the [Inject] attribute. Then it will call them with the resolved instances of their parameter types. (this is called Method or Property injection)
So when contructor injection is not enoughpossible you can Kernel.Inject to fill in your dependencies for a given instance.
You can read more about this here: Ninject Injection Patterns

NHibernate and IoC IInterceptor

I have been trying to implement a solution similar to what Ayende posts in his MSDN article, Building a Desktop To-Do Application with NHibernate. Fortunately, Skooletz wrote a similar article that follows up what I am trying to accomplish with his 3 part blog post on NHibernate interceptor magic tricks (1, 2, 3). I am having trouble getting my POCO object's parametered constructor to be called by NHibernate when instantiating the object.
When I remove the protected parameterless constructor, NHibernate complains with an InvalidProxyTypeException: "The following types may not be used as proxies:
YourNamespace.YourClass: type should have a visible (public or protected) no-argument constructor". If I then add in the protected default constructor, NHibernate no longer complains, but the dependency (in the overloaded constructor) is never called causing the application to barf with a NullReferenceException at runtime when the dependency is not satisfied.
public MyClass
{
IRequiredDependency dependency;
public MyClass(IRequiredDependency dependency)
{
this.dependency = dependency;
}
protected MyClass() {}
}
I just can't seem to get NHibernate to call the overloaded constructor. Any thoughts?
In the configuration of the IoC container, you have to declare your type with the dependency in addition to the dependency itself.
container.RegisterType<IRequiredDependency, RequiredDependency>();
container.RegisterType<MyClass, MyClass>();
I missed that little tidbit from Pablo's post (where he registers the Invoice class in addition to its dependency, IInvoiceTotalCalculator) as I am using Unity instead of Windsor.
One additional note: I found is that if you would like to have any other overloaded constructors, make them internal, leave the default constructor as protected and have only a single public constructor that contains your dependencies. This tidbit helped tighten up some of my API design for the classes.

No parameterless constructer defined for this object when putting EnabledDelete=true on LinqDataSource

If I have a LinqDataSource without EnabledDelete, EnabledUpdate, EnabledInsert, it works fine, but as soon as I add those properties to the data source, I get the error:
No parameterless constructor defined for this object.
Here is an answer that helped me solve the issue from the MSDN forums:
LinqDataSource requires a default constructor on the DataContext. If you are working in a web application or website project, the Linq to SQL designer should have created a default constructor and connection string for you when you dragged tables from the database onto the design surface.
Did you create your DataContext and drag tables onto the design surface from a webapp or website project? Open the Lib.NorthwindDataContext class that was generated and see if it has the default constructor.
If you really want, you could also use LinqDataSource without the default constructor by handling the ContextCreating event and providing your own context instance.
As the error indicates, you need to provide a parameterless constructor for the class.
public class MyClass
{
public MyClass()
{
// This is the parameterless constructor
}
// rest of the class members goes here.
}
The system requires a parameterless constructor when it is required to create instances of a class automatically. It cannot determine the meaning of the parameters of your other constructors so it depends on this constructor.
Even if your constructor does nothing it will still work, though you may want it to provide useful defaults for your class properties.

Constructor dependency injection with NHibernate 2.1 and StructureMap

I've read somewhere that NHibernate 2.1 supports constructor dependency injection for it's entites.
How do I go about configuring StructureMap and NHibnerate 2.1 to get this up and running ?
I realize this is an old question, but in case it might be useful.
EDIT: Original posted links weren't effective for NHib 2.1, found better info.
For NHibernate 2.1, you can create an Interceptor and override the Instantiate method and have your container create your instances there. Here is an example
If you wanted to do property injection instead, you can use the same technique but do your work in the onLoad method instead.
By setting up StructureMap across all of your entities (classes etc) and then using the interface for each of those as the signature for the constructor of a class...when you instantiate the class that has a dependency in its constructor StructureMap will auto inject it for you!
[PluginFamily("Default")]
public interface IWidget1
[Pluggable("Default")]
public class Widget1 : IWidget1
[PluginFamily("Default")]
public interface IAnotherWidget
[Pluggable("Default")]
public class AnotherWidget : IAnotherWidget
{
public AnotherWidget(IWidget widget)
{
...
}
}
IAnotherWidget _anotherWidget = ObjectFactory.GetInstance<IAnotherWidget>();
Something like that!
This may be of use too: Can I replace the call to Activator.CreateInstance() in NHibernate?
And this: http://devlicio.us/blogs/billy_mccafferty/archive/2007/02/05/inject-di-container-into-domain-objects-with-nhibernate.aspx

Applying Spring .Net Advice to HibernateTemplate object

I have an class for auditing:
public class AuditAfterAdvise : IAfterReturningAdvice
This is applied to a Dao class in my Spring.Net configuration, using a RegularExpressionMethodPointcutAdvisor.
The Dao class implementation calls HibernateTemplate.SaveOrUpdate(object entity) to commit changes.
I would like to be able to apply AuditAfterAdvise class to the HibernateTemplate SaveOrUpdate() method used in my Dao, rather than the methods on the Dao itself.
The NHibenate/Spring setup is to use a LocalSessionFactoryObject for the Dao. Is this possible?
Thanks.
It certainly should be possible.
Instead of configuring the Dao, add the advice to the object definition for the LocalSessionFactoryObject. The RegularExpressionPointCutAdvisor should continue to work -- just applied to a different object.
I'm assuming the HibernateTemplate is retrieved from a Spring.NET object factory...