If I understand correctly Project 2 is some shared project which is used in other projects which use Unity for Dependency Injection. Unity uses property injection in this case by annoting the property with the DependencyAttribute
.
Simple Injector is capable of doing property injection. Property injection however should only be used for optional dependencies. And as you're running into a NullReferenceException
this dependency is not optional!
So you should move the IGenericRepo<ServiceObj>
to the constructor of IService
. This makes it clear to users of IService
that it needs a repository to function correctly. This becomes especially useful when you would unittest IService
as the constructor will in this case clearly communicates that it needs a repository.
By moving the dependency to the constructor Simple Injector will inject the repository correctly or throw an ActivationException
if the configuration is not valid.
You can test, and I recommend doing this, by calling container.Verify()
as you can read here: Verify the container’s configuration. This will make the application to fail fast.
If project 2 can't be refactored or for some other compelling reason constructor injection is not an option, Simple Injector does support property injection. It does however not support this out-of-the-box. One of the design principles of Simple Injector is to never fail silently and therefore only Explicit property injection is advised. This will gives the container the opportunity to use its Diagnostic Services and fail fast if the configuration is invalid.
As you can read in the referenced documentation, there are 2 ways of doing it property injection:
- By registering an initializer with a call to
container.RegisterInitializer()
- By implementing
IPropertySelectionBehavior
Option 2 will let Simple Injector check the dependencies using the Diagnostics Services automatically. When verifying all 'initializers' are executed also, but the code in lambda isn't checked for lifestyles etc.
Simple Injector does not encourage its users to take a dependency on the container and it therefore does not contain any Atrributes
which you can use out-of-the-box such as Unity has the DependencyAttribute
.
So you have 2 options here:
- Let project 1 also take a dependency on Unity (which it indirectly already has!, yuck) and create an implementation of
IPropertySelectionBehavior
to search for the Unity DependencyAttribute
- Create your own custom
Attribute
in project 2 and annotate _serviceRepo
which this custom attribute also.
The only difference between 1 and 2 is which attribute is searched for.
If you can't touch project 2, option 2 isn't possible. Implementing IPropertySelectionBehavior
is straightforward:
// custom attribute only for option 1
public class ImportAttribute : Attribute { }
class UnityDependencyPropertySelectionBehavior : IPropertySelectionBehavior
{
public bool SelectProperty(Type type, PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(DependencyAttribute)).Any();
}
}
You can configure the container using this custom IPropertySelectionBehavior
by:
container.Options.PropertySelectionBehavior =
new UnityDependencyPropertySelectionBehavior();
To summarize:
Move the dependency to the constructor as it is not a optional dependency. In other words use constructor injection!
If there are compelling reasons not to do this implement IPropertySelectionBehavior