I'm unsure of how to fix my current situation. I'm attempting to create a task:
public class whatever
{
[Dependency]
public IReportingBL ReportingBL { get; set; }
private whatever()
{
...task factory creation, etc.
}
private readonly static Lazy<whatever> _instance = new Lazy<whatever>(() => new whatever());
public static whatever Instance { get { return _instance.Value; }
public Task GetStuff()
{
return _taskFactory.StartNew(() =>
{
return ReportingBL.Method1;
});
}
}
ReportingBL doesn't get resolved. If I create a new instance of ReportingBL inside the thread then the layers below it don't get resolved.
How do I go about getting unity to work in this situation?
You are applying the Singleton Design Pattern. This is a pattern that is frown upon and considered an anti-pattern by some. In Dependency Injection terminology the Singleton pattern can be considered an Ambient Context, which is a pattern that should hardly ever be used in the context of Dependency Injection.
The Singleton Design Pattern does not work well with Dependency Injection, because:
With Dependency Injection it is the application's Composition Root who is in control of creating instances and caching them; not the instance itself.
Having consumers depend on the public Instance field, causes the consumers to violate the Dependency Inversion Principle and disallows the instance from being replaced, mocked, decorated or intercepted. This hinders maintainability and testability of your application.
Further more, in your code I don't see any calls to the Unity DI framework. Please remember that a DI container is not a magical tool that will allow classes to be initialized 'by them selves'. In your code you new up whatever directly; Unity is not involved in this. Unity (or any DI library for that matter) can only auto-wire the object if it is in control of it. In other words, you will have to call container.Resolve<whatever>() for Unity to build up your instance.
Although you could call container.Resoolve from within the Lazy<T> factory delegate, this forces the class to take a dependency on the container itself, which is commonly referred to as the Service Locator anti-pattern.
Instead, I propose the following changes to your design:
Use constructor injection instead of property injection. Property injection leads to Temporal Coupling.
Make the Composition Root and the container responsible for wiring up object graphs.
Stay away from the Singleton design pattern; use the container's Singleton Lifestyle instead.
This results in the following code:
public interface IWhatever
{
Task GetStuff();
}
public class Whatever : IWhatever
{
private readonly IReportingBL reportingBL;
public whatever(IReportingBL reportingBL) {
this.reportingBL = reportingBL;
}
public Task GetStuff() {
return _taskFactory.StartNew(() => {
return ReportingBL.Method1;
});
}
}
// Some consumer of whatever
public class MyController : Controller
{
private readonly IWhatever whatever;
public MyController(IWhatever whatever) {
this.whatever = whatever;
}
public ActionResult Index() {
return View(this.whatever.GetStuff());
}
}
In your composition root, you can configure the class as follows:
var container = new UnityContainer();
container.RegisterType<IReportingBL, ReportingBL>(
new ContainerControlledLifetimeManager());
container.RegisterType<IWhatever, Whatever>(
new ContainerControlledLifetimeManager());
var controller = container.Resolve<MyController>();
controller.Index();
Related
Trying to use autofac for dependency injection by property.
The instance is always null and there is no dependency injected.
Below is class where the property needs to be injected.
public class UserAccount
{
public IAccountService AccountService { get; set; }
public string Message()
{
return AccountService.Message();
}
}
I have tried three different ways to inject the property but none was successful
Method 1 :
builder.Register(c => {
var result = new UserAccount();
var dep = c.Resolve<IAccountService>();
result.SetDependency(dep);
return result;
});
Method 2 :
builder.RegisterType<UserAccount>().PropertiesAutowired();
Method 3 :
builder.Register(c => new UserAccount { AccountService = c.Resolve<IAccountService>()});
PS : Method injection of above is welcomed.
You should prevent letting your container create data-centric objects, such as your UserAccount entity. This leads to complicated scenarios, such as the one you are in now.
In general, your DI Container should resolve only components—those are the classes in your system that contain the application's behavior, without having any interesting state. Those types of classes are typically long lived, or at least, longer lived than data-centric objects.
Data-centric objects, like entities, can best be created by hand. Not doing so would either lead to entities with big constructors, which easily causes the constructor over-injection code smell. As remedy, you might fall back on using Property Injection, but this causes a code smell of its own, caused Temporal Coupling.
Instead, a better solution is to:
Create entities by hand, opposed to using a DI Container
Supply dependencies to the entity using Method Injection, opposed to using Property Injection
With Method Injection, your UserAccount would as follows:
// This answer assumes that this class is an domain entity.
public class UserAccount
{
public Guid Id { get; set; }
public byte[] PasswordHash { get; set; }
public string Message(IAccountService accountService)
{
if (accountService == null)
throw new ArgumentNullException(nameof(accountService));
return accountService.Message();
}
}
This does move the responsibility of supplying the dependency from the Composition Root to the entity's direct consumer, though. But as discussed above, this is intentional, as the Composition Root in general, and a DI Container in particular, should not be responsible of creating entities and other data-centric, short-lived objects.
This does mean, however, that UserAccount's direct consumer should inject that dependency, and with that, know about existence of the dependency. But as that consumer would be a behavior-centric class, the typical solution is to use Constructor Injection at that stage:
public class UserService : IUserService
{
private readonly IAccountService accountService;
private readonly IUserAccountRepository repo;
public UserService(IAccountService accountService, IUserAccountRepository repo)
{
this.accountService = accountService;
this.repo = repo
}
public void DoSomething(Guid id)
{
UserAccount entity = this.repo.GetById(id);
var message = entity.Message(this.accountService);
}
}
Using method 3, you need to register AccountService, i.e.
builder.RegisterType<AccountService>().As<IAccountService>();
builder.Register(c => new UserAccount { AccountService = c.Resolve<IAccountService>()});
And when you use UserAccount, make sure it is created using Autofac.
I have a controller's constructor in which I want to instantiate an object that gets access to the repository via dependency injection.
like this:
ContactController.cs: I get an error because I don't pass an IContactRepository
private ContactOperationsFacade contactOperator;
ContactController(){
contactOperator = new ContactOperationsFacade(//I want to use DI here);
}
ContactOperationsFacade.cs:
private readonly IContactRepository contactRepository;
public ContactOperationsFacade(IContactRepository contactRepositor){
this.contactRepository = contactRepository;
}
How can I instantiate this ContactOperationsFacade object in the controller's constructor still using DI for the repository?
In asp.net core you can do DI chaining as long as scopes allow it. So if A depends on B and the controller wants A you just add both A and B to the di container (ConfigureServices part of your code) and the container will figure it out.
Read more here https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1
ContactController should follow The Explicit Dependencies Principle
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
Also classes should depend on abstractions and not coupled to concretions.
So assuming something like
public class ContactOperationsFacade: IContactOperationsFacade { //<-Note interface/contract
private readonly IContactRepository contactRepository;
public ContactOperationsFacade(IContactRepository contactRepositor){
this.contactRepository = contactRepository;
}
//...
}
The controller should depend on the abstraction that the facade is derived from
public class ContactController: Controller {
private readonly IContactOperationsFacade contactOperator;
public ContactController(IContactOperationsFacade contactOperator){
this.contactOperator = contactOperator;
}
//...
}
And assumes that all the interfaces and implementations are registered with the DI container.
services.AddScoped<IContactOperationsFacade, ContactOperationsFacade>();
once all dependencies are registered the service provider should resolve them when activating the controller.
I am fairly familiar with concepts of service locator and dependency injection, but there is one thing that gets me confused all the time, i.e., to implement dependency injection for an application we must use some sort of service locator at the start. Please consider the following code,lets say we have some simple DAL class:
public class UserProviderSimple : IUserProvider
{
public void CreateUser(User user)
{
//some code to user here
}
}
And then in the Business Logig Layer we have some simple class that uses IUserProvider that is injected using constructor injection:
public class UserServiceSimple : IUserService
{
public IUserProvider UserProvider { get; set; }
public UserServiceSimple(IUserProvider userProvider)
{
UserProvider = userProvider;
}
public void CreateUser(User user)
{
UserProvider.CreateUser(user);
}
}
Now we may have couple of classes like that and use constructor injection everywhere, but in the main class where the application starts, all these types have to be resolved anyway, hence we must use a service locator to resolve all these types, for example, here I will create a singleton service locator class to resolve all the dependencies at the start of a console application like this:
public class ServiceLocator
{
private readonly UnityContainer _container;
private static ServiceLocator _instance;
public static ServiceLocator Instance()
{
if (_instance == null)
{
_instance = new ServiceLocator();
return _instance;
}
return _instance;
}
private ServiceLocator()
{
_container = new UnityContainer();
_container.RegisterType<IUserProvider, UserProviderSimple>();
_container.RegisterType<IUserService, UserServiceSimple>();
}
public T Resolve<T>()
{
return _container.Resolve<T>();
}
}
class Program
{
private static IUserService _userService;
private static void ConfigureDependencies()
{
_userService = ServiceLocator.Instance().Resolve<IUserService();
}
static void Main(string[] args)
{
ConfigureDependencies();
}
}
So it seems like some kind of service locator is always used at the start of the application, hence using service locator is inevitable and it's not correct to always call it an anti-patern right (unless it's used not in the root of the application)?
You misunderstand what a Service Locator is. You do understand the part that it is an anti-pattern, which is good, but what you're missing is that the pattern is not about the mechanics, but the role it plays in the application. In other words:
A DI container encapsulated in a Composition Root is not a Service Locator - it's an infrastructure component.
There is nothing inherently wrong with calling the class encapsulating the DI container bootstrapping code ServiceLocator, but you could also call it a Startup, Bootstrap or ContainerWrapper, it is just a naming convention.
On the other hand ServiceLocator as a design pattern is usually considered an anti-pattern since it becomes a hard dependency for the rest of the code and makes changes and testing hard and unpredictable. In your code it is Resolve<T> method which you would want to stay away from to avoid the consequences.
https://en.m.wikipedia.org/wiki/Service_locator_pattern
And to answer your question, a piece of code is usually required to initialize the DI container in any case even when it is hidden from you as part of a bigger DI framework itself, some frameworks though allow configuring your container from the configuration file too. Hope it helps!
I have struggled with the same question for quite some time. I have make the experience that you usually do not need a ServiceLocator (btw: best description of this anti pattern here and what you can do to avoid it in the corresponding, very awsome, book).
Please see the refactoring of your code below. The basic idea here is that you have just one root object that acts as the composition root (Program) and all child dependencies of the complex object graph below that root are automatically resolved by the container.
public class Bootstrapper
{
private readonly UnityContainer _container;
private Bootstrapper()
{
_container = new UnityContainer();
}
public Program Intialize()
{
this.ConfigureDependencies(UnityContainer container);
return this.GetCompositionRoot();
}
private void ConfigureDependencies()
{
_container.RegisterType<IUserProvider, UserProviderSimple>();
_container.RegisterType<IUserService, UserServiceSimple>();
_container.RegisterType<Program, Program>();
}
private Program GetCompositionRoot()
{
return _container.Resolve<Program>();
}
}
public class Program
{
public Program(IUserService userService)
{
_userService = userService ?? throw AgrumentNullExcpetion(nameof(userService));
}
static void Main(string[] args)
{
var program = new Bootstrapper().Initialize();
program.Run();
}
public void Run()
{
// Do your work using the injected dependency _userService
// and return (exit) when done.
}
}
There are some situations where it does not fit, then YES it's an anti pattern.
We have to look if there are valid usages of the patterns, and for Service Locator there are several use cases.
In a typical line of business application, you should avoid the use of service. It should be the pattern to use when there are no other options.
For instance, inversion of control containers would not work without service location. It's how they resolve the services internally.
There is a question I always ask myself when I'm using a Factory pattern inside my code (C#, but it applies to any language I suppose).
I have a "Service" that takes care of interacting with my database, do stuff with objects and interacts with my object model.
This Service uses a Factory sometimes to delegate the instanciation of an object.
But this factory obviously needs to interact by itself with the database to instanciate my object properly.
Is it a good/bad practice to pass the Database context to the Create method for example?
Like this :
var myNewObject = MyFactory.Create(myDatabaseContext);
the other way would be to let the Service always be the only one to talk with the database.
var myNewObject = MyFactory.Create();
var extraProperty = myDatabaseContext.Get(something);
myNewObject.extraProp = extraProperty;
Any advices?
The idea of passing the database context into the factory create method is called method injection. This is a form of dependency injection, so you are on the right track.
You can use dependency injection to manage your database context inside of your factory via the constructor. The factory could look something like this:
public class MyFactory
{
private readonly IMyDbContext dbContext;
public MyFactory(IMyDbContext dbContext)
{
this.dbContext = dbContext;
}
public object Create()
{
// Use the dbContext, etc
}
}
Constructor injection is usually favored because it leaves method signatures less cluttered. We will also most likely have one type of database context so there will be no need to take advantage of polymorphism based on some other runtime information.
You can choose to use a Dependency Injection Container like Ninject or, my favorite, SimpleInjector to manage the dependencies for you.
It is OK to have the DbContext only used by the factory. One thing you may want to watch out for is that a user of your factory may not realize that the factory is calling to the database. This could be a bad thing and have negative performance implications. Typically, construction information is passed into the factory method, not initialized into the factory method from the DB. You could even take it a step further and use the Repository Pattern to abstract away some more of the data access logic if you think it is necessary and you don't have that already.
To learn more about Dependency Injection, in case you are unfamiliar, you can start here.
My ideal structure may look like this:
public class MyFactory : IFactory
{
public object Create(object someProperty)
{
// build object
}
}
public class MyService
{
private readonly IMyDbContext dbContext;
private readonly IFactory factory;
public MyService(IMyDbContext dbContext, IFactory factory)
{
this.dbContext = dbContext;
this.factory = factory;
}
public void DoWork()
{
var property = dbContext.Get(something);
var newObj = factory.Create(property);
// Use stuff
}
}
In the project I am working on, we try to keep all database access inside the Service. If the Factory needs objects that must be loaded from the DB, the Service should load them and pass them to the Factory. If the object returned by the Factory shall be persisted, the Service should add it to the DbContext.
This corresponds to the second way you have shown. The advantage is that the Factory can be unit tested without any need to mock the DbContext.
If you want to keep the DB access inside the Factory anyways, I would inject the DbContext into the constructor of the Factory, instead of passing it to the Create() method.
The Service gets an instance of the Factory injected in turn (instead of accessing static methods of the Factory). Again, this will make mocking much easier.
public class Service {
private readonly IMyDbContext _myDatabaseContext;
private readonly IMyFactory _myfactory;
public Service (IMyDbContext myDbContext, IMyFactory myfactory) {
_myDatabaseContext = myDbContext;
_myfactory = myfactory
}
public void Create() {
var extraProperty = myDatabaseContext.Get(something);
var myNewObject = _myFactory.Create(extraProperty);
_myDatabaseContext.Add(myNewObject);
_myDatabaseContext.SaveChanges();
}
}
I'm using Munq as the DI container in a MVC3 project. I have a service layer that retrieves a DTO from a repository. Depending on a property in that DTO I need to use one of two strategies to perform calculations on the DTO. I can register a named type in the container e.g.
Container.Register<ICalculation>("Type1", c => new Type1Calculation);
Container.Register<ICalculation>("Type2", c => new Type2Calculation);
Then I can refer directly to the container when trying to instantiate the appropriate strategy e.g.
var calc = Container.Resolve<ICalculation>(dto.ServiceType);
But this leaves me with a dependency on the container itself with the associated coupling and testing issues. What do I need to pass into the service constructor that would allow me to get the correct calculation but without the dependency on the container? Should I pass in a factory instead so the dependency is in the factory and not in the service class?
Not sure about Munq, but Autofac allows you to pass around Funcs, so that you can skip all factories altogether:
public class Foo
{
public Foo(Func<string, IBar> barFactory) { }
}
Check if Munq allows for such behavior.
Otherwise -- yes, you'll have to resort to hand-written factories to provide yet another level of indirection.
I've added the Munq solution to this. First the factory which includes the IDependencyResolver interface to allow the factory to use the container to resolve dependencies in the factory method:
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
Then in Global.asax.cs register the appropriate interfaces/classes, passing in the container to the factory. So now I can set up my tests and the only extra dependency is IDependencyResolver within the factory:
ioc.Register(c => new CalculationFactory(c));
ioc.Register<ICalculation>("Type1", c => c.Resolve<Type1Calculation>());
ioc.Register<ICalculation>("Type2", c => c.Resolve<Type2Calculation>());
ioc.Register<ICalculation>("InvalidType", c => c.Resolve<InvalidCalculation>());