I am kind of new to Unity and DI terminology, hence trying to understand how does it work. I have following code which implements DI using Unity container.
public class DashboardService: IDashboardService
{
private readonly IRepository<USERROLE> repoUserRole;
private readonly IRepository<INSTITUTION> repoInstitution;
public DashboardService(
IRepository<USERROLE> repoUserRole, IRepository<INSTITUTION> repoInstitution)
{
this.repoUserRole = repoUserRole;
this.repoInstitution = repoInstitution;
}
public List<USERROLE> GET(List<string> Id)
{
// Use repoUserRole object to get data from database
}
}
This service is being called by the controller:
public class DashboardController : ApiController
{
private readonly IDashboardService dashboardService;
public DashboardController(IDashboardService dashboardService)
{
this.dashboardService = dashboardService;
this.mapper = mapper;
}
//Action method which uses dashboardService object
}
Here is the Unity configuration:
var container = new UnityContainer();
container.RegisterType(typeof(IDashboardService), typeof(DashboardService))
.RegisterType(typeof(IRepository<>), typeof(Repository<>));
return container;
Questions:
As of now, my code works fine, but if I comment out the DashboardService constructor, I am getting the null repository objects.
I am resolving the dependencies in Unity for repository interfaces, so why I am getting null there?
Is there any way to pass the repository dependancy without using the constructor pattern?
if I comment out the DashboardService constructor, I am getting the null repository objects.
When you don't add a constructor to a class, C# will generate a public parameterless constructor for you during compilation. This causes Unity to call that 'invisible' parameterless constructor, and that's why none of your private fields are initialized.
To prevent these kinds of accidental programming errors, always make sure you enable "treat all warnings as errors" in your project's properties build tab. This will make sure the compiler stops compiling because it detects these uninitialized fields.
Is there any way to pass the repository dependancy without using the constructor pattern?
Yes there is, but every other method you could use leads to either a code smell or an anti-pattern. Constructor injection is in almost all cases the best solution.
Related
New to Simple Injector, trying to get some pieces working for a prototype. I am creating a WPF application that uses Simple Injector and ReactiveUI, but can't seem to get explicit property injection via attribute to trigger. The specific example I am working through is just testing injection of a logger. The plan is to roll this into a decorator, but I have run across the need for attribute injection with previous projects/DI libraries. Just want to verify I am able to use it.
Snippet of the bootstrapping:
private Container RegisterDependencies(Container container = null)
{
container ??= new Container();
// Container initialization that must precede dependency registration
// occurs here
// Enable property injection via the [Import] attribute
container.Options.PropertySelectionBehavior =
new ImportPropertySelectionBehavior();
SimpleInjectorInitializer initializer = new SimpleInjectorInitializer();
Locator.SetLocator(initializer);
Locator.CurrentMutable.InitializeSplat();
Locator.CurrentMutable.InitializeReactiveUI();
container.UseSimpleInjectorDependencyResolver(initializer);
container.RegisterConditional(
typeof(ILogger),
c => typeof(NLogLogger<>)
.MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
container.Register<MainWindow>();
container.Register<ISystem, System>(Lifestyle.Singleton);
container.Verify();
return container;
}
An instance of the System is requested from the DI container in the static RunApplication called from Main:
var system = container.GetInstance<ISystem>();
And here is the property injection in the system:
public class System : ISystem
{
[Import] public ILogger Logger { get; set; }
public System()
{
// Logger is null here. NullReferenceException is thrown
Logger.LogInfo("Creating System");
}
}
At this point in the constructor, the Logger property is null and attempt to log fails with exception. I should mention the ILogger is my own abstraction of NLog. If I instead perform constructor injection:
public System(ILogger logger)
Simple Injector picks up on this and resolves the dependency fine. I have tried changing the Import attribute to a different custom-defined Dependency attribute, no change. Have also tried just instantiating the logger as a singleton, same behavior.
Really appreciate any ideas, I'm running dry on searching forums, the SimpleInjector/ReactiveUI docs, and Steven's DI book.
Edit - here is the PropertySelectionBehavior code as well:
public class PropertySelectionBehavior<T> : IPropertySelectionBehavior
where T : Attribute
{
public bool SelectProperty(
Type implementationType, PropertyInfo propertyInfo) =>
propertyInfo.GetCustomAttributes(typeof(T)).Any();
}
public class ImportPropertySelectionBehavior :
PropertySelectionBehavior<ImportAttribute> { }
2nd Edit - I can take out all of the initialization related to ReactiveUI and still reproduce same behavior. New sample looks like:
private Container RegisterDependencies(Container container = null)
{
container ??= new Container();
container.Options.PropertySelectionBehavior =
new ImportPropertySelectionBehavior();
// Logger registration
container.RegisterConditional(
typeof(ILogger),
c => typeof(NLogLogger<>)
.MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
// UI registration
container.Register<MainWindow>();
//container.Register<MainWindowViewModel>();
container.Register<ISystem, System>(Lifestyle.Singleton);
container.Verify();
return container;
}
You are using the Logger property from inside System's constructor. Properties, however, are only initialized after the constructor finished. If you remove Simple Injector from the equation, and fallback to plain old C#, you would see the same. For instance:
var system = new System() // <-- constructor call
{
Logger = new NLogLogger<System>() // Logger_set is called after the ctor
};
If you run this code, you will see the same NullReferenceException thrown by the constructor of System.
What this means is that you shouldn't use any properties from inside your constructor. Even more broadly, from a DI perspective, you shouldn't use any service inside your constructor (or during construction for that matter) as is described by Mark Seemann here.
Update, the explicit property injection is working fine. It occurs after construction. I imagine there are design reasons for this, although somehow it was contrary to my mental model that the property injection would be performed on-demand/on first use.
Planning on experimenting a bit more to see what control is available over the timing to resolve property dependencies. If anyone who is more experienced has any advice on that or can point me to additional documentation I would welcome it. The decorator sounds like the more elegant way to make sure the logger is available as expected and allow independent lazy loading of decoratee concerns. Some discussion here:
SimpleInjector - "Lazy" Instantiate a singleton that has dependencies on first use
I have an API controller, in the constructor an instance of EmployeeService is instantiated with Unity.
I'd like inject the value of myTest in the constructor of EmployeeService,
that's means an instance of Repository<Employee> will be created and the content of _myString will "TestString"
If it's possible how set the container ?
Thanks,
[RoutePrefix("api/employee")]
public class EmployeeController : ApiController
{
string myTest = "TestString";
readonly IEmployeeService _employeeService;
public EmployeeController(IEmployeeService employeeService)
{
_employeeService = employeeService;
}
}
public class EmployeeService : ServiceBase, IEmployeeService
{
private readonly IRepository<Employee> _repoEmployee;
private readonly string _myString;
public EmployeeService(IRepository<Employee> repoEmployee, string myString)
{
_repoEmployee = repoEmployee;
_myString = myString
}
}
container
.RegisterType<IRepository<Employee>, Repository<Employee>>()
.RegisterType<IEmployeeService, EmployeeService>());
My Solution :
.RegisterType<IEmployeeService, EmployeeService>(
new InjectionConstructor(
typeof(IRepository<Employee>),
"MySetting"));
To use in the service class some parameters (keys) coming from the
web.config. These parameters are read in the controller and send to
the service class
The controller should not be concerned with reading from the configuration file. In doing so, it violates the Single Responsibility Principle. This causes maintainability issues; issues that you are already experiencing, since your design causes you trouble with testing and configuring your DI library.
Since these are configuration values, they will not change during the lifetime of the application (changing the config file will cause the application to restart). Because of this, there is no reason for the controller to read them (over and over again). Instead, you can read them once during startup and inject them into the class that needs that configuration value.
In case there are multiple classes that need that configuration value, you changes are high that you are missing an abstraction. For instance, instead of injecting a connection string into many classes, consider creating an ConnectionFactory that hides the connection string from those classes and allows creating a SqlConnection on request.
But in your case, I imagine doing something like this:
TimeSpan timeOut = TimeSpan.FromSeconds(Int32.Parse(
ConfigurationManager.AppSettings["timeOut"]));
container.RegisterType<IRepository<Employee>, Repository<Employee>>();
container.RegisterType<IEmployeeService, EmployeeService>());
container.Register<IEmployeeService>(new InjectionFactory(c =>
new EmployeeService(
c.Resolve<IRepository<Employee>>(),
timeOut)));
Reading configuration values at start up has the following advantages:
It prevents your application code from depending on the configuration system itself. This makes your code more reusable, testable and maintainable.
It allows the application to fail fast at start up in case it is configured incorrectly.
It allows you to verify the correctness of your DI configuration in a test suite, without having to have the exact same configuration file in your unit test project.
I am using ASP.NET MVC WebApi 2 and injecting concrete types into controllers using Unity 3 and this Unity MVC bootstrapper.
The issue here is that one the registered types initialises an Entity Framework 6 DbContext for every resolve:
public sealed class EntityFrameworkUnitOfWork : IUnitOfWork
{
internal DbContext Context { get; private set; }
public EntityFrameworkUnitOfWork()
{
Context = new SomeContext();
}
public void Commit()
{
Context.SaveChanges();
}
public void Dispose(bool disposing)
{
if (disposing)
{
if (Context != null)
{
Context.Dispose();
Context = null;
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
For example, the EntityFrameworkUnitOfWork would be constructor injected into a controller like this:
public class UserController : ApiController
{
public UsersController(IUserRepository userRepository, IUnitOfWork unitOfWork)
{
// unitOfWork is a EntityFrameworkUnitOfWork
}
// ...
}
When the relevant MVC controller disposes, I need the Dispose() method to be called on the above EntityFrameworkUnitOfWork type, which in turn will dispose of the underlying DbContext.
Registering this type with Unity:
Container.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>(
new DisposingTransientLifetimeManager()
);
I am using the DisposingTransientLifetimeManager lifetime manager, as suggested in this article, thinking that it would automatically dispose of my IDisposable types. It seems that I still need to call on Container.Teardown(someInstance). This is not possible for me to do as the MVC Bootstrapper is handling all DI resolving.
Where and how can I perform the teardown of these initialised types?
It would be ideal to perform this teardown when the relevant MVC controller destructs, but perhaps this can also occur at the end of the HTTP request?
EDIT:
The IDisposables that are injected aren't necessarily accessible from the controller. For example, I could also inject a IUserService into a controller which itself (the IUserService class) is injected with an IUserRepository and an IUnitOfWork. I could chain Dispose methods from the IUserService to dispose of them, but this would requires changes to hundreds of controllers and services. Ideally I should be able to call container.Dispose() somewhere to have Unity dispose all injected disposables.
EDIT 2:
RaraituL brought something else to mind. IUnitOfwork does not implement IDisposable, only EntityFrameworkUnitOfWork does. This essentially means that the an MVC controller wouldn't be able to call on a dispose method as it only knows of IUnitOfWork. This is another reason why Unity should do this - it created the IDisposables so it should dispose of them too.
Sounds like you want a PerRequestTransientLifetimeManager. That will be something you will have to build. It's not hard and since you are using Unity 3 most of the work is already done for you.
public class PerRequestTransientLifetimeManager : ILifetimePolicy
{
public object GetValue()
{
// will always create a new object (Transient)
return null;
}
public void SetValue(object newValue)
{
// No point in saving to http context if not disposable
if (newValue is IDisposable)
{
var perRequestLifetimeManager = new PerRequestLifetimeManager();
perRequestLifetimeManager.SetValue(newValue);
}
}
public void RemoveValue()
{
// can't remove since transient didn't keep a reference
}
}
You'll need Unity.Mvc nuget package if the PerRequestLifetimeManager class is missing. You'll also need to register the UnityPerRequestHttpModule using Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule
I should point out from MS site
Although the PerRequestLifetimeManager lifetime manager works
correctly and can help in working with stateful or thread-unsafe
dependencies within the scope of an HTTP request, it is generally not
a good idea to use it when it can be avoided, as it can often lead to
bad practices or hard to find bugs in the end-user's application code
when used incorrectly. It is recommended that the dependencies you
register are stateless and if there is a need to share common state
between several objects during the lifetime of an HTTP request, then
you can have a stateless service that explicitly stores and retrieves
this state using the Items collection of the Current object.
You could use the UnityHierarchicalDependencyResolver in the same NuGet package you already reference (Unity.AspNet.WebApi). Then register your services you want disposed with the HierarchicalLifetimeManager. This dependency resolver creates and disposes a new child container on every Web Api request. When a Unity container is disposed, all built up objects in that container are also disposed.
IUnityContainer rootContainer = new UnityContainer();
GlobalConfiguration.Configuration.DependencyResolver =
new UnityHierarchicalDependencyResolver(rootContainer);
rootContainer.RegisterType<IUnitOfWork, EntityFrameworkUnitOfWork>
(new HierarchicalLifetimeManager());
I'm using Ninject.MVC3.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<Repository>().To<Repository>();
}
Registering them like so in the App_Start.
It works just fine on controller that request this repository.
However I also have a few classes that need this repository.
[Inject]
public MemberShipService(Repository repository)
{
this.Repository = repository;
}
^Example from a class constructor.
I've tried constructor injection this simply gives me errors because it requests an argument for the constructor.
Property injection simply doesn't work.
Do I need to do something extra to make constructor or property injection work in asp.net mvc3? I haven't done any other configuration inside NinjectWebCommon other then the line I posted above.
You'll need to resolve an instance of the class using dependency resolver in order to use it, create an instance of your MemberShipService using:
var memberShipService =
DependencyResolver.Current.GetService(typeof(MemberShipService)) as MemberShipService;
That will bind your instance variable Repository using your constructor that you specified.
I see lead developers writing code like this and upon reading Mark Seemann's book "Dependency Injection in .NET" I'm wondering if the specific "new" is "foreign", thus "Bastard Injection"??
public class SessionInitServiceManager
{
protected readonly ICESTraceManager _traceManager;
protected readonly ILogger _logger;
protected readonly IAggregateCalls _aggregator;
protected readonly IMultiCoreRepository _repository;
public SessionInitServiceManager(ICESTraceManager traceManager,
ILogger logger,
IAggregateCalls aggregator,
IMultiCoreRepository repository)
{
_traceManager = traceManager;
_logger = logger;
_aggregator = aggregator;
_repository = repository;
}
public SessionInitServiceManager() : this(new CESTraceManager(),
new Logger("BusinessServices.authenticateUser"),
new Aggregator(),
new RepositoryFactory().BuildMultiCoreRepository()) { }
This for sure looks like a classic example of Bastard Injection. The reason why is because you have what appears as four Foreign Defaults. Foreign Default refers to a default value in which the type comes from a different module/project/DLL. I would propyl include namespace into that definition, because name spaces can signify boundaries in which at a future point you make breakout into its own module. This is more of being mindful about that when you decide to use a local default (Would I split this into its own module in the future?).
The way this wouldn’t be Bastard Injection would be that all these classes live within the same module. The thing that makes this so bad is because you drag the dependencies along, and now your class is tightly coupled to these classes. If I choose to use my own version of logging I have to take along the DLL for logging and so on, even though I don’t use, negating the benefits of modular application design.
I happened to have borrowed that book, dependency injection in .NET, from a friend. I see what you are saying. I do believe that this is "bastard injection". It is a brutal term, but I suppose fitting after all ColdFusion (cough) has a "CFABORT" tag as part of the language.
Also, I noticed a good article, blog post How not to do dependency injection - the static or singleton container.
Basically, before we begin, let's get something out of the way:
Dependency Injection != Using an IoC container"
Here is the kicker, "This is the birth of the static container. Instead of changing the constructor of the controller to take in the dependency, we are just changing the line where the service is instantiated to resolve it using the container instead."
public class HomeController
{
private readonly IExampleService _service;
public HomeController()
{
_service = Container.Instance.Resolve<IExampleService>();
}
public ActionResult Index()
{
return View(_service.GetSomething());
}
}