Removing Dependency From Controller Constructor in MVC - c#

I am creating a MVC application using NINject as my IOC. I am trying to separate my business logic from controller. And so I don't want my controller constructor creates for my any Dependency Object i.e. I dont want to pass my interface in the constructor and than it gets resolved through IOC container. It should be the responsibility of the business logic layer. I am trying to achieve something like below.
public BusinessHolidayController()
{
}
// GET: BusinessHoliday
public ActionResult Index(Product product)
{
string model = invoke<IProduct>().GetSum(product);
return View(model);
}

What you are above to do is leaning toward Service Locator Pattern which is anti-pattern and a dangerous pattern. Its disadvantages are greater than its advantages.
There are four basic DI patterns -
Constructor Injection
Property Injection
Method Injecton
Ambient Context
For MVC controller, you want to use Constructor Injection, because it is the best pattern of the above four patterns especially for controller.
It should be the responsibility of the business logic layer.
No. Composite Root should be placed entry point of the application such as Global.asax.
For more information, you want to read Mark Seemann's Dependency Injection in .NET.

Related

Need to pass class object to ninject

So I am working on API and using Ninject for DI & IoC. I know how the basic code works using Ninject but in the constructor of one of the classes an object of Logger is being sent. Rather than send it in constructor design item I would like to pass it in NinjectWebCommon.cs file.
public GAMonthlyAPIController() : this(new GAMonthlySQLReader(new NullLogger()))
This is the constructor.
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
This is the entry in NinjectWebCommon.cs I would like to bind it in NinjectWebCommon.cs rather than default value. How would I pass that? I don't even know what to search for, so I could find answers.
The most practical way to apply the dependency injection pattern is to use constructor injection. This means that the classes GaMonthlyAPIController depend on should be passed in through the constructor, rather than hard-coded inside of the controller.
public class GAMonthlyAPIController
{
private readonly IGAMonthlySQLReader gaMonthlySqlReader;
public GAMonthlyAPIController(IGAMonthlySQLReader gaMonthlySqlReader)
{
this.gaMonthlySqlReader = gaMontlySqlReader
?? throw new ArgumentNullException(nameof(gaMontlySqlReader));
}
// implementation of controller...
}
This should be the only constructor for your controller class. The controller itself doesn't know anything about GAMontlySqlReader or any of its dependencies.
The same goes for GAMonthlySQLReader - it will allow any ILogger implementation to be injected through the constructor.
The idea is that it puts the composition root of the application in charge of how the dependencies are composed together, meaning you can easily switch them around later without making any changes to the components that you are composing. So, Ninject would be used inside of your composition root to map types to their abstraction, and then will build object graphs of all of those dependencies composed together.
kernel.Bind<ILogger>().To<MyLoggerClass>();
kernel.Bind<IGAMonthlyReader>().To<GAMonthlySQLReader>();
For each of the application services, you would allow Ninject to instantiate them (so it can supply the dependencies) rather than using the new keyword inside of your application (new can be used for DTOs and Models, though).
I think you need to add Ninject.Web.WebApi using nuget to your Web Api project. Then use Ninject for creating ApiControllers:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
And add the Bind() for GAMonthlyAPIController. No need to create a default constructor for your controller.
Have a look to this post:
http://nodogmablog.bryanhogan.net/2016/04/web-api-2-and-ninject-how-to-make-them-work-together/

C# Dependency Injection with 3 projects on same Solution

I have a solution with separate projects. The structure is like this:
1 - the web project
2 - the Aplicacao, that is called by the controllers of 1 to do the logic
3 - the Dominio, that has the classes of my solution
4 - the Dados, that has the entity framework stuff...
So, when I have a POST to register a new user, the UsuarioController (UC) is called. The UC has to instanciate a UsuarioAplicacao (UA) passing a usuario. The UA has to instanciate a UsuarioRepositorio (UR) passing a usuario as parameter and here it will be salved to the database.
I'm used to instanciate the class I need inside the constructor of the class, like so:
public ActionResult Registrar (Usuario usuario)
{
if (ModelState.IsValid)
{
var _usuarioApp = new UsuarioAplicacao();
_usuarioApp.Salvar(usuario);
rest of the code...
}
}
But, while studing, I've learned that this isn't quite right. I should use the dependency injection (DI)...
So, using DI with the constructor, I can't figure out how to do it...
I've tried like this in my controller:
private UsuarioAplicacao _usuarioAplicacao;
public UsuarioController (UsuarioAplicacao usuarioAplicacao)
{
this._usuarioAplicacao = usuarioAplicacao;
}
then, on my UsuarioAplicacao (class that do the logics and call UsuarioRepositorio to save the object into the DB):
private readonly UsuarioRepositorio _usuarioRepositorio;
public UsuarioAplicacao (UsuarioRepositorio usuarioRepositorio)
{
this._usuarioRepositorio = usuarioRepositorio;
}
and finnaly, inside my UsuarioRepositorio (class responsable for saving tha data into the DB via Entity Framework):
private readonly Contexto _contexto;
public UsuarioRepositorio(Contexto contexto)
{
this._contexto = contexto;
}
(_contexto is my EF context class)
These are my onstructors. But I'm getting Null Reference Exceptions...
Can you guys help me with dependency injection?
Ninject I couldn't understand how to use either...
thanks in advance
you are getting null references because you didn't configure any dependency injection. Simply passing a parameter on the controller constructor is not enough, you have to actually tell the depedency injector how to construct your dependencies.
Using Unity, you do something like this on your WebApiConfig (or global.asax if on mvc)
public static void UnityContext_OnRegisterComponents(Microsoft.Practices.Unity.UnityContainer container)
{
container.RegisterType<ICarRepository, CarRepository>(new HierarchicalLifetimeManager());
}
Now, for the concept of dependency injection, it is used to keep low coupling among projects. Your controller must not know your Business rules, neither how to create objects that belong to another assembly.
Example: When you create your repositories and isntantiate your entities directly on the controller, you are creating a dependency between those assemblies, making it really hard to test your code later, also making it a lot more complex.
In terms of architecture, I use something like this:
Web - Front end
Business - Where you do your business Rules
Contracts - Where you declare your data transfer objects
Data - Where you declare your entities, and entity framework do low level stuff, like opening connections, saving things to the database and etc, and where you declare your repositories
In that architeture:
Web access Contracts and Business
Business access Contracts and Data
Data Doesnt Access Anything
Business will ask Data for entities, Data will answer with the entity models from your database, and any manipulation you need to do, will be done in the business, returning a data transfer object (of the Contracts assembly), which will them be used in your front end, either as it is returned, or defining a new model to fit the transfer object into your front end.
In this scenario, keeping dependency injection in mind, it would create a coupling if the business layer knew how to create Data Layer objects, so instead of doing this, you configura a dependency injection container, and that object will be responsible for instantiating everything that every layer needs, keeping all your projects decoupled.

Facade usage and naming

Numerous business logic services within my program need access to a common set of non-business logic services, such as email, printing, messaging (message boxes and prompts), and logging. I am planning on creating a facade to encapsulate EmailService, PrintService, MessageService, and LogService so that each business logic service just needs one constructor parameter to the facade class, instead of four parameters to each of the services.
So instead of
public BusinessLogicService(IEmailService emailService, IPrintService printService, IMessageService messageService, ILogService logService)
{
this.EmailService = emailService;
this.LogService = logService;
this.MessageService = messageService;
this.PrintService = printService;
}
I'll have this
public BusinessLogicService(ISomeFacade facade)
{
this.SomeFacade = facade;
}
My questions are:
Is this the correct usage of the facade pattern? If not, how should I be doing this?
I assume that having a standard set of services that are needed by a lot of business services is pretty common, so is there a standard naming convention for this sort of facade that encapsulates EmailService, PrintingService, MessagingService, LoggingService, and possibly some other non-business logic services that I need in the future?
What you've described is not facade but rather service locator (see for discussion on that pattern - Is ServiceLocator an anti-pattern?). Note that trouble coming up with the name is very good sign of creating IKitchenSink interface.
To be facade it must somehow simplify interaction with the services - maybe have one ArchveMessage call that will orchestrate working with all 4 services.
Number of constructor parameters generally does not matter* since one likely will be creating such objects with dependency injection framework anyway. Using DI framework may also take care of most "logging" responsibility by providing a way to log start/end/error cases for all method calls.
*) large number of injected dependencies indicate too many responsibilities of the class and need to be looked at from that point of view.

Dependency Injection in Facade layer

I am creating an application and I am using Façade design pattern, in which request will go through
Controller (webApi) -> Façade -> Business -> Repository
And I am using Unity config to initialize my objects (façade, business, and repository), in the controller layer I will set Unity config and initialize all objects. But my doubt is how I can pass repository object to business layer.
Like I am using repository methods call in business layer and it will definitely require repository object so I injected that in business layer constructor. See below code:
public class MessageBusiness : IMessageBusiness
{
IMessageRepository _messageRepository;
public MessageBusiness(IMessageRepository messageRepository)
{
_messageRepository = messageRepository;
}
public int AddMessage(RS.DomainEntity.Model.Message newMessage)
{
return _messageRepository.AddMessage(newMessage);
}
}
Now should I pass this repository object from Façade layer?
public class MessageFacade : IMessageFacade
{
IMessageBusiness _messageBusiness;
public MessageFacade(IMessageBusiness messageBusiness)
{
_messageBusiness = messageBusiness;
}
public int AddMessage(RS.DomainEntity.Model.Message newMessage)
{
return _messageBusiness.AddMessage(newMessage);
}
}
If not then I can I inject this repository in my business layer? OR if YES then we will need to pass this in Façade as well, it’s like passing object from one layer to another. Is that the right behavior?
Also If you give the ans for first question then how can I perform integration testing in my Façade layer. Any idea? Any help is much appreciated. Thanks in advance.
Regards,
Vivek
Now should I pass this repository object from Façade layer?
Not really, you don't have to. In such straightforward graph like yours, you only need a unity controller factory and facades injected into controllers. Unity will do the rest, to initialize a facade it will go for a business service and since it needs a repository, Unity will find and inject one, assuming of course you register all interfaces to implementations in advance.
Btw. I definitely recommend Unit of Work instead of Repository. UoW is more general and allows the client to access all possible repositories. You can think of it like of a container to all repositories.

Confusion about DI, IoC and service locators

I have read various articles about IoC, DIP, DI and Service Locators but I'm a bit confused which is which because some articles have too vague examples and some other articles have just some specific examples without mentioning other cases.
Could you please clear this up for me, looking at the examples below and shortly explaining which examples match which pattern?
manually passing interface to constructor:
class Consumer
{
public Consumer(IStore store){...}
}
...
Consumer c = new Consumer(new ConcreteStore());
the same as the first example but using some 3rd party library (Unity, Windsor, Ninject)
the same as the first example but using BaseStore class instead of IStore interface
passing dependency to some other method, not to constructor:
class Consumer
{
public BySomething(IStore store){...}
}
...
Consumer c = new Consumer();
c.BySomething(new ConcreteStore());
passing dependencies masked inside of some other interface (bonus for this solution - when some other things are invented in the "world" and Consumer wishes to use them, we don't have to change constructor argument but just update IWorld; and we can completely replace entire World with something else when testing):
interface IWorld
{
IDictionary<string,IStore> Stores { get; set; }
IDictionary<string,ICityMap> Maps { get; set; }
...
}
class Consumer
{
public Consumer(IWorld world){...}
public BySomething(string store, string city){...}
}
...
IWorld myWorld = new HeavenlyWorld();
... // adding stores, maps and whatnot
Consumer c = new Consumer(myWorld);
a sub-question: in this case, is IWorld a service locator or not exactly?
passing a call-back function or delegate (.NET Action in this case):
c.BySomething(store, city, new Action(() => {...} ));
I added this case because the article Inversion of Control states that every callback is IoC. Is it true?
Everything you listed is a form of Dependency Injection.
"Poor Man's" DI
DI using an IoC container
"Poor Man's" DI again. DI works whether you are using an interface or an abstract class.
Method Injection
I'm not sure what you're asking here. It sounds like you want to change the instance of IWorld at runtime, which might be a case for Property Injection instead of Constructor Injection. Properties are oft used for optional dependencies or those that can change. Whether you then set that dependency at run-time with a Service Locator or other means is up to you. Another thing to consider is that IWorld might just depend on context, in which case you could do a context-depdendent constructor injection, the details of which are beyond the scope of this question.
Not related to DI
Every time you pass a dependency as a constructor/method argument, that's Dependecy Injection. It can be manual, like in most of your examples, or automatic using a DI Container aka IoC Container.
Using a container means the objects using deps are constructed by the container. You could ask the container directly for that service and in that case, there's a static property or method ( think DependecyResolver in asp.net mvc) that exposes that service. In that case you're using the Service Locator pattern. IWork in your example is not a locator, it's just a dependency.
To continue with the dependency resolver example, you register all relevant types into a container, the container is build then registered as the dependency resolver. The asp.net mvc framwork then uses the resolver (the Service Locator - SL) to instantiate controllers, views and all the deps these require.
To use the SL pattern is ok as part of a framework, but it's not ok if you're using it in your app to instantiate objects, because it couples the code to the locator. Sometimes is the only solution but 99% you is just an anti-pattern.

Categories

Resources