Should AggregateService be used as a container to store common dependencies? - c#

I have a base controller class which uses aggregate services in autofac to inject its dependencies. In a class derived from base controller, I need to access a service which is a part of aggregate container. Which one is a better way?
public Interface ICommonControllerDependencies
{
ICookieService CookieService{ get; }
IAuthenticationService AuthenticationService{ get; }
}
public abstract class BaseController : Controller
{
protected readonly ICommonControllerDependencies Dependencies;
protected BaseController(ICommonControllerDependencies dependencies)
{
this.Dependencies = dependencies;
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.ViewData[UserName] = Dependencies.AuthenticationService.UserName;
base.OnActionExecuting(filterContext);
}
protected ActionResult RedirectToDefaultPage()
{
var page = Dependencies.CookieService.GetDefaultPageCookie(Request, RouteData);
//Do Something
}
}
public class BaseReportController : BaseController
{
public BaseReportController(ICommonControllerDependencies dependencies)
: base(dependencies)
{
_cookieService = dependencies.CookieService;
}
}
OR
public class BaseReportController : BaseController
{
public BaseReportController(
ICookieService cookieService,
ICommonControllerDependencies dependencies)
: base(dependencies)
{
_cookieService = cookieService;
}
}

The AggregateService is intended to be what isolates your subclass from changes in the super class, and enable changes in the superclass without breaking subclasses.
If you go for option 1, you couple the subclass to your superclass, thus loosing the intended isolation.
Without knowing more about your design I would go for option 2. I don't think that I can anticipate ServiceA to always be there. Taking an explicit dependency on IServiceA in the subclass, that class can live on happily ignorant about changes going on in the superclass internals.

When you need an Aggregate Service (as the Autofac documentation calls it), this could be a sign of violating the Single Responsibility Principle, that states that a class should do one thing, and only one thing.
In other words, the Aggregate Service pattern is a code smell*.
Having big base classes is a code smell as well, since base classes tend to grow and grow to big and complicated classes, that contain a lot of code that not all sub types use. Instead, the general advice is to favor composition over inheritance.
With UI frameworks such as ASP.NET MVC however, this is not always easy, since most frameworks themselves promote inheritance.
Try to extract the logic of the base class to separate dependencies, especially when that code in the base class isn't used by all sub types. For instance, you might be able to refactor the RedirectToDefaultPage method to the following:
public class DefaultPageRedirector
{
private readonly ICookieService cookieService;
public DefaultPageRedirector(ICookieService cookieService)
{
this.cookieService = cookieService;
}
public ActionResult RedirectToDefaultPage(
Controller controller)
{
var page = this.cookieService.GetDefaultPageCookie(
controller.Request, controller.RouteData);
//Do Something
}
}
This way you can inject the DefaultPageRedirector only into Controller types that actually need it.
For the OnActionExecuting it is different, since it gets called for each and every sub type. However, the ViewData["UserName"] property will probably not be used by every View in the system and in that case you should consider returning the UserName as part of the (staticly typed) ViewModel object. If it is used by most views, you might want to consider using a partial view, because you might have some repetitive code in your views (The DRY principle holds not only for code, but for every part in the system).
This will probably get rid of most code in the base class, which probably also removes most of the dependencies in the base (if not all).
* Note that a code smell doesn't mean there is always a problem. To quote Wikipedia: "code smell is any symptom in the source code of a program that possibly indicates a deeper problem."

I would think that it depends on whether you have IserviceA registered in the container or not and how you anticipate your design evolving.
Personally, I would go with the first option if you don't anticipate removing serviceA from the ICommonControllerDependencies interface. It just seems simpler to inject a single interface. If you think that you may remove serviceA at some time, I would consider going with the second option as it removes the coupling between the service and the controller dependencies within the BaseReportController. I think the second option more closely follows the Law of Demeter.

Related

Get resolved dependancies of IRepository with AutoFac

With interfaces set up like so:
public interface IRepository { };
public interface IFirstRepository : IRepository { };
public interface ISecondRepository : IRepository { };
public interface IThirdRepository : IRepository { };
And a Controller that needs some but not all of these repositories:
public class TestController : BaseController
{
private IFirstRepository mFirstRepository;
private ISecondRepository mSecondRepository;
// Standard DI for MVC
public TestController(IFirstRepository first, ISecondRepository second)
{
mFirstRepository = first;
mSecondRepository = second;
}
}
And BaseController looks like:
public class BaseController : Controller {
public IEnumerable<IRepository> GetRepos()
{
// One solution is to use reflection
// to get all properties that are IRepositories.
// Something along the lines of;
return typeof(this).GetProperties().Where(prop=>prop is IRepository);
// But is there a way to use the AutoFac context
// to get the repos, rather than use reflection?
// it surely already has that info since it
// was able to call the constructor correctly?
}
}
Is there a way BaseController can utilize the AutoFac context and existing info to get the collection of the IRepository instances requested by the TestController?
Autofac surely already has that info since it was able to call the constructor with the correct instances.
NB: The only reason I don't just use reflection here is performance concerns.
There's not an easy way to do this out of the box. If you find yourself in this situation, generally it means you have an interface design problem. There's an FAQ walking through an example of why this is, as well as some options.
If you really, really need to do this, then I'd probably look at adding metadata to each of the registrations where you have a metadata entry for each controller requiring that particular repository, then filter at the constructor using the metadata filter attribute. Again, the FAQ I mentioned walks through this and shows examples.
But if it was me working in this system... I'd step back and look at my interface design to see how to get away from needing this sort of filter in the first place. If they all can't be treated equally (Liskov substitution principle) then it indicates there are different interfaces required.

Conditional inheritance: base class depend on environment variable

I have two abstracts classes, 'ValidationsWithStorage' inherits 'Validations'
public abstract class Validations {
// methods..
}
public abstract class ValidationsWithStorage : Validations {
// ...
}
I also have a class:
public abstract class TestsValidations : T
T should be depend on the environment variable:
Environment.GetEnvironmentVariable("useStorage")
If this variable is null I want that T will be Validations.
Else, I want that T will be ValidationsWithStorage.
What is the best way to do it?
Thanks
I am not sure you can do this with inheritance. This is not the logic of inheritance. It will be better if you use something like factory pattern and change your current deisgn.
May be you can do something like this. I didn't test but i think it will be easier like this:
public interface Validations
{
void ValidationsStuff();
}
public class ValidationsWithStorage : Validations
{
public void ValidationsStuff()
{
//do something
}
}
public class TestsValidations : Validations
{
public void ValidationsStuff()
{
//do something
}
}
public class ValidationsFactory
{
public Validations geValidationsComponent(string useStorage)
{
if (string.IsNullOrEmpty(useStorage))
return new ValidationsWithStorage();
else
return new TestsValidations();
}
}
I don't think you can do what you want to do in the way you do it.
Why not let your class TestValidations take a parameter in its constructor of either type Validations or ValidationsWithStorage. If they both follow the same interface, your TestsValidations class wouldn't need to know (or care) which of the two it's working with.
So basically:
Create an interface for your Validations and ValidationsWithStorage class
Check your environment variable
Pass the correct class into the TestsValidation constructor according to the environment variable
Does that help?
You can do that using conditional compilation:
public abstract class TestsValidations
#if USESTORAGE
: ValidationsWithStorage
#else
: Validations
#endif
{
}
You can set it in project configuration or by passing additional parameters to msbuild: /p:DefineConstants="USESTORAGE"
I don't think this is good design, but it is doable.
If you want to work with inheritance I think your problem will be solved if you use the Generic Constraints
What not to do:
I don't recommend conditionally changing the definition of a class. There are weird, one-off reasons to do that, but we rarely encounter them and shouldn't make them a normal part of how we write code.
I also don't recommend a factory. A factory implies that you're making a decision at runtime, in production, whether to use a "real" class or a test class. A factory only makes sense if some data available only at runtime determines which implementation you want to use. For example, if you want to validate an address, you might use its country to determine whether to us a US validator, Canadian validator, etc, like this:
var validator = _validatorFactory.GetValidator(address.Country);
Also, that means that the "test" class would be referenced from your production code. That's undesirable and a little strange.
What to do:
If you aren't making such a decision at runtime then this should be determined in the composition root - that is, in the part of our application that determines, at startup, which classes we're going to use.
To start with, you need an abstraction. This is most often an interface, like this:
public interface IValidator
{
ValidationResult Validate(Something value);
}
The class that needs the validation would look like this:
public class ClassThatNeedsValidation
{
private readonly IValidator _validator;
public ClassThatNeedsValidation(IValidator validator)
{
_validator = validator;
}
// now the method that needs to use validation can
// use _validator.
}
That's dependency injection. ClassThatNeedsValidation isn't responsible for creating an instance of a validator. That would force it to "know" about the implementation of IValidator. Instead, it expects to have an IValidator provided to it. (In other words its dependency - the thing it needs - is injected into it.)
Now, if you're creating an instance of ClassThatNeedsValidation, it might look like this:
var foo = new ClassThatNeedsValidation(new ValidationWithStorage());
Then, in your unit test project, you might have a test implementation of IValidator. (You can also use a framework like Moq, but I'm with you - sometimes I prefer to write a test double - a test class that implements the interface.)
So in a unit test, you might write this:
var foo = new ClassThatNeedsValidation(new TestValidator());
This also means that TestValidator can be in your test project, not mixed with your production code.
How to make it easier:
In this example:
var foo = new ClassThatNeedsValidation(new ValidationWithStorage());
You can see how this might get messy. What if ValidationWithStorage has its own dependencies? Then you might have to start writing code like this:
var foo = new ClassThatNeedsValidation(
new ValidationWithStorage(
connectionString,
new SomethingElse(
new Whatever())));
That's not fun. That's why we often use an IoC container, a.k.a dependency injection container.
This is familiar if we use ASP.NET Core, although it's important to know that we don't have to use ASP.NET Core to do this. We can add Microsoft.Extensions.DependencyInjection, Autofac, Windsor, or others to a project.
Explaining this is somewhat beyond the scope of this answer, and it might be more than what you need right now. But it enables us to write code that looks like this:
services.AddSingleton<IValidator, ValidationWithStorage>();
services.AddSingleton<Whatever>();
services.AddSingleton<ISomethingElse, SomethingElse>();
services.AddSingleton<ClassThatNeedsValidation>();
Now, if the container needs to create an instance of ClassThatNeedsValidation, it will look at the constructor, figure out what dependencies it needs, and create them. If those classes have dependencies it creates them too, and so on.
This takes a minute or several or some reading/trying if it's a new concept, but trust me, it makes writing code and unit tests much easier. (Unless we do it wrong, then it makes everything harder, but that's true of everything.)
What if, for some reason, you wanted to use a different implementation of IValidator in a different environment? Because the code above is executed once, at startup, that's easy:
if(someVariable = false)
services.AddSingleton<IValidator, OtherValidator>();
else
services.AddSingleton<IValidator, ValidationWithStorage>();
You're making the decision, but you're making it once. A class that depends on IValidator doesn't need to know about this decision. It doesn't need to ask which environment it's in. If we go down that route, we'll end up with stuff like that polluting all of our classes. It will also make our unit tests much more difficult to write and understand. Making decisions like this at startup - the composition root - eliminates all of that messiness.

How does the SOLID open/closed principle fit in with Dependency Injection and dependency inversion

I am starting to apply SOLID principles, and am finding them slightly contradictory. My issue is as follows:
My understanding of dependency inversion principle is that classes should depend on abstractions. In practice this means classes should be derived from interfaces. All fine so far.
Next my understanding of the open/closed principle is that after a certain cut off point, you should not alter the contents of a class, but should extend and override. This makes sense so far to me.
So given the above, I would end up with something like this:
public interface IAbstraction
{
string method1(int example);
}
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
and then at time T, method1 now needs to add " ExtraInfo" onto its returned value. Rather than altering the current implementation, I would create a new class that extends Abstraction and make it do what I needed, as follows.
public Class AbstractionV2 : Abstraction
{
public override string method1(int example)
{
return example.toString() + " ExtraInfo";
}
}
And I can see the reason for doing this is that only the code I want to call this updated method will call it, and the rest of the code will call the old method.
All makes sense to me - and I assume my understanding is correct??
However, I am also using dependency injection (simple injector), so my implementations are never through a concrete class, but instead are through my DI configuration, as follows:
container.Register<IAbstraction, Abstraction>();
The issue here is that under this setup, I can either update my DI config to be:
container.Register<IAbstraction, AbstractionV2>();
In which case all instance will now call the new method, meaning I have failed to achieve not changing the original method.
OR
I create a new interface IAbstractionV2 and implement the updated functionality there - meaning duplication of the interface declaration.
I cannot see any way around this - which leads me to wonder if dependency injection and SOLID are compatible? Or am I missing something here?
TL;DR
When we say that code is "available for extension" that doesn't automatically mean that we inherit from it or add new methods to existing interfaces. Inheritance is only one way to "extend" behavior.
When we apply the Dependency Inversion Principle we don't depend directly on other concrete classes, so we don't need to change those implementations if we need them to do something different. And classes that depend on abstractions are extensible because substituting implementations of abstractions gets new behavior from existing classes without modifying them.
(I'm half inclined to delete the rest because it says the same thing in lots more words.)
Examining this sentence may help to shed some light on the question:
and then at time T, method1 now needs to add " ExtraInfo" onto its returned value.
This may sound like it's splitting hairs, but a method never needs to return anything. Methods aren't like people who have something to say and need to say it. The "need" rests with the caller of the method. The caller needs what the method returns.
If the caller was passing int example and receiving example.ToString(), but now it needs to receive example.ToString() + " ExtraInfo", then it is the need of the caller that has changed, not the need of the method being called.
If the need of the caller has changed, does it follow that the needs of all callers have changed? If you change what the method returns to meet the needs of one caller, other callers might be adversely affected. That's why you might create something new that meets the need of one particular caller while leaving the existing method or class unchanged. In that sense the existing code is "closed" while at the same time its behavior is open to extension.
Also, extending existing code doesn't necessarily mean modifying a class, adding a method to an interface, or inheriting. It just means that it incorporates the existing code while providing something extra.
Let's go back to the class you started with.
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
Now you have a need for a class that includes the functionality of this class but does something different. It could look like this. (In this example it looks like overkill, but in real-world example it wouldn't.)
public class SomethingDifferent : IAbstraction
{
private readonly IAbstraction _inner;
public SomethingDifferent(IAbstraction inner)
{
_inner = inner;
}
public string method1(int example)
{
return _inner.method1 + " ExtraInfo";
}
}
In this case the new class happens to implement the same interface, so now you've got two implementations of the same interface. But it doesn't need to. It could be this:
public class SomethingDifferent
{
private readonly IAbstraction _inner;
public SomethingDifferent(IAbstraction inner)
{
_inner = inner;
}
public string DoMyOwnThing(int example)
{
return _inner.method1 + " ExtraInfo";
}
}
You could also "extend" the behavior of the original class through inheritance:
public Class AbstractionTwo : Abstraction
{
public overrride string method1(int example)
{
return base.method1(example) + " ExtraInfo";
}
}
All of these examples extend existing code without modifying it. In practice at times it may be beneficial to add existing properties and methods to new classes, but even then we'd like to avoid modifying the parts that are already doing their jobs. And if we're writing simple classes with single responsibilities then we're less likely to find ourselves throwing the kitchen sink into an existing class.
What does that have to do with the Dependency Inversion Principle, or depending on abstractions? Nothing directly, but applying the Dependency Inversion Principle can help us to apply the Open/Closed Principle.
Where practical, the abstractions that our classes depend on should be designed for the use of those classes. We're not just taking whatever interface someone else has created and sticking it into our central classes. We're designing the interface that meets our needs and then adapting other classes to fulfill those needs.
For example, suppose Abstraction and IAbstraction are in your class library, I happen to need something that formats numbers a certain way, and your class looks like it does what I need. I'm not just going to inject IAbstraction into my class. I'm going to write an interface that does what I want:
public interface IFormatsNumbersTheWayIWant
{
string FormatNumber(int number);
}
Then I'm going to write an implementation of that interface that uses your class, like:
public class YourAbstractionNumberFormatter : IFormatsNumbersTheWayIWant
{
public string FormatNumber(int number)
{
return new Abstraction().method1 + " my string";
}
}
(Or it could depend on IAbstraction using constructor injection, whatever.)
If I wasn't applying the Dependency Inversion principle and I depended directly on Abstraction then I'd have to figure out how to change your class to do what
I need. But because I'm depending on an abstraction that I created to meet my needs, automatically I'm thinking of how to incorporate the behavior of your class, not change it. And once I do that, I obviously wouldn't want the behavior of your class to change unexpectedly.
I could also depend on your interface - IAbstraction - and create my own implementation. But creating my own also helps me adhere to the Interface Segregation Principle. The interface I depend on was created for me, so it won't have anything I don't need. Yours might have other stuff I don't need, or you could add more in later.
Realistically we're at times just going to use abstractions that were given to us, like IDataReader. But hopefully that's later when we're writing specific implementation details. When it comes to the primary behaviors of the application (if you're doing DDD, the "domain") it's better to define the interfaces our classes will depend on and then adapt outside classes to them.
Finally, classes that depend on abstractions are also more extensible because we can substitute their dependencies - in effect altering (extending) their behavior without any change to the classes themselves. We can extend them instead of modifying them.
Addressing the exact problem you mentioned:
You have classes that depend on IAbstraction and you've registered an implementation with the container:
container.Register<IAbstraction, Abstraction>();
But you're concerned that if you change it to this:
container.Register<IAbstraction, AbstractionV2>();
then every class that depends on IAbstraction will get AbstractionV2.
You shouldn't need to choose one or the other. Most DI containers provide ways that you can register more than one implementation for the same interface, and then specify which classes get which implementations. In your scenario where only one class needs the new implementation of IAbstraction you might make the existing implementation the default, and then just specify that one particular class gets a different implementation.
I couldn't find an easy way to do this with SimpleInjector. Here's an example using Windsor:
var container = new WindsorContainer();
container.Register(
Component.For<ISaysHello, SaysHelloInSpanish>().IsDefault(),
Component.For<ISaysHello, SaysHelloInEnglish>().Named("English"),
Component.For<ISaysSomething, SaysSomething>()
.DependsOn(Dependency.OnComponent(typeof(ISaysHello),"English")));
Every class that depends on ISaysHello will get SaysHelloInSpanish except for SaysSomething. That one class gets SaysHelloInEnglish.
UPDATE:
The Simple Injector equivalent is the following:
var container = new Container();
container.Register<ISaysSomething, SaysSomething>();
container.RegisterConditional<ISayHello, SaysHelloInEnglish>(
c => c.Consumer.ImplementationType == typeof(SaysSomething));
container.RegisterConditional<ISayHello, SaysHelloInSpanish>(
c => c.Consumer.ImplementationType != typeof(SaysSomething))
Modules become closed to modification once they are referenced by other modules. What becomes closed is the public API, the interface. Behavior can be changed via polymorphic substitution (implementing the interface in a new class and injecting it). Your IoC container can inject this new implementation. This ability to polymorphically substitute is the 'Open to extension' part. So, DIP and Open/Closed work together nicely.
See Wikipedia:"During the 1990s, the open/closed principle became popularly redefined to refer to the use of abstracted interfaces..."

Inheritance dependency injection simplification

This one is a bit complicated, so please read everything through. I'm working on some code that implements the MVVM Pattern for WPF. I have a XAML Markup extension that looks for a specific property on the datacontext. (It's a long and fun story, but out of scope) My view model will be set as the Dataconext on the view.
Here's an example of how I have implemented my BaseViewmodel...
public class ViewModelBase : IViewModelBase
{
protected CommandManagerHelper _commandManagerHelper;
//todo find a way of eliminating the need for this constructor
public OrionViewModelBase(CommandManagerHelper commandManagerHelper)
{
_commandManagerHelper = commandManagerHelper;
}
private IExampleService _exampleService;
public IExampleService ExampleService
{
get
{
if (_exampleService == null)
{
_exampleService = _commandManagerHelper.GetExampleService();
}
return _exampleService;
}
}
}
What's going on there is that I'm effectively lazy loading the _exampleService. I'm sure it's possible to use Lazy, but I've not got round to implementing that just yet.
My Xaml Markup will be looking for and making use of my the ExampleService it could also be used by code within the view model. It's going to be used all over the application.
A point to note is that my application will have only one instance of the ExampleServer that will be passed around, calling GetExampleService from anywhere in the application will return the same instance of the object. There will only be one instance of the ExampleService object, although it is not coded as a singleton.
Here is an example of how I am inheriting from my ViewModelBase...
internal class ReportingViewmodel : ViewModelBase
{
private readonly IReportingRepository _reportingRepository;
public ReportingViewmodel(CommandManagerHelper commandManagerHelper, IReportingRepository reportingRepository) : base(commandManagerHelper)
{
_reportingRepository = reportingRepository;
}
}
This code works and works great. However, having to type ": base(commandManagerHelper)" every time that I implement a new inherited member of the ViewModelBase is prone to mistakes. I'm likely to have 100's of these implementations and each one needs to be right.
What I'm wondering is.... is there a way of implementing the same behaviour respecting the SOLID principles and not having to call the base constructor every time I implement an instance of the ViewModelBase?
i.e. I'd like the ReportingViewModel to look like this
internal class ReportingViewmodel : ViewModelBase
{
private readonly IReportingRepository _reportingRepository;
public ReportingViewmodel(IReportingRepository reportingRepository)
{
_reportingRepository = reportingRepository;
}
}
but still have the ExampleService populated correctly.
I'm currently considering using the Service locator pattern for this, I'm also considering using a Singleton and I'm open to other better solutions.
The reason that I'm asking the question rather than diving in with code is that I know that the Singleton is generally an anti-pattern, to me it signifies that something else is wrong in the code.
I've just read an article on IoC and it's slating the Service locator pattern here's the article http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container.
You can't get out of calling the base constructor.
It doesn't really matter that IExampleService is only instantiated once and shared. Your ViewModelBase doesn't (and shouldn't) "know" that. All it needs to know is that whatever is injected implements that interface.
That's one of the big benefits, because when you unit test classes you can inject a mocked version of that interface. If classes depended on a static reference to something buried within a base class then it wouldn't be possible to replace it with a mock for testing.
I use ReSharper. (Am I allowed to say that? I don't mean to advertise.) Among many other things it generates those base constructors for you. I'm sure at some point that's got to get built in to Visual Studio.

How to inject a dependency into a base class if child doesn't know it?

I have an abstract base class Command that depends on ICommandLogger interface:
public abstract class Command
{
public Command(ICommandLogger cmdLogger) { /* ... */ }
}
And now all the inheritors are look like:
public class ConcreteCommand : Command
{
public ConcreteCommand(CommandLoggersNamespace.ICommandLogger cmdLogger)
: base(cmdLogger)
{
}
}
I don't like they are forced to know about ICommandLogger (which they do not use).
How to get around of this? Or what are the reasons for complete redesign?
There's a problem in your design that causing you all this trouble. First of all, logging is a cross-cutting concern and you should prevent polluting classes with that. Second, if you let the base class implement logging, what is the next cross-cutting concern that will be added on the logger base class. The second you start adding another cross-cutting concern, the base class will violate the Single Responsibility Principle. Your base class will eventually grow to a big unmanageable class with lots of dependencies, and lot's of reasons to change.
Instead, try adding logging as a decorator. Your design however, prevents you from effectively doing that, since you will probably have dozens of concrete commands and they would all need their own decorator. But the core problem with your design is that you mix data and behavior. Let the command be nothing more than a class containing some data (DTO) and extra the commands logic into its own class; let's call that the command handler.
On top of that, let command handlers implement this interface:
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
This will look like this:
public class MoveCustomerCommand
{
public Guid CustomerId;
public Address NewAddress;
}
public class MoveCustomerCommmandHandler : ICommandHandler<MoveCustomerCommand>
{
public void Handle(MoveCustomerCommand command)
{
// behavior here.
}
}
What's interesting about this design is that since all business logic is now hidden behind one narrow interface, and this interface is generic, it becomes very easy to extend the behavior of the system by wrapping handlers with decorators. For instance a logging decorator:
public class LoggingCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> decoratee;
public LoggingCommandHandlerDecorator(
ICommandHandler<TCommand> decoratee, ILog log)
{
this.decoratee = decoratee;
this.log = log;
}
public void Handle(TCommand command)
{
this.log.Log("Executing " + typeof(TCommand).Name + ": " +
JsonConvert.Serialize(command));
try
{
this.decoratee.Handle(command);
}
catch (Exception ex)
{
this.log.Log(ex);
throw;
}
}
}
Since this LoggingCommandHandlerDecorator<TCommand> is generic, it can be wrapped around any ICommandHandler<TCommand>. This allows you to let consumers take a dependency on some ICommandHandler<TCommand> (such as ICommandHandler<MoveCustomerCommand>) and you can add crosscutting concerns to all business logic without changing a single line of code.
This will in most cases remove the need to use a base class completely.
You can read more about this type of design here.
If you are doing dependency injection via the constructor, there's no way around this. An alternative is dependency injection via property setters. Personally, I prefer the constructor method, because to me, that communicates that this class requires this dependency whereas a property-injected dependency communicates an optional dependency.
If you go the constructor route, and your base class takes a lot of dependencies, you can alleviate some of the pain by creating an aggregate service so that the base only needs one parameter injected instead of many.
If they don't use the command logger you may try to not set any at all, like this:
public ConcreteCommand()
: base(null)
{
}
If this does not work (throws an Exception) you may try to implement a phony command logger and instantiated that one:
public ConcreteCommand()
: base(new MyPhonyCommandLogger())
{
}
If you don't want those phony instances around, have a single instance statically available:
public ConcreteCommand()
: base(MyPhonyCommandLogger.Instance)
{
}
Well another way of looking at it is that the ConcreteComand class does have a dependency on ICommandLogger. It inherited it when it derived from Command.
Therefore there is no way around what you are doing that makes sense other than for ConcreteCommand to accept the dependency on behalf of its base class - think about it not in terms of "ConcreteCommand has a Command" but more like "ConcreteCommand is a Command"
Think about how you'd handle wanting to override the base class logging behaviour if you somehow were able to get he base class dependency on ICommandLogger to somehow "sneak past" the construction of ConcreteCommand...
If you want to be able to provide "base like" functionality (base.Log("foo")), etc) and you absolutely do not want ConcreteComand to know about ICommandLogger, then you can always switch to "has a" type scenario - whereby Command is just a member variable of ConcreteCommand (a silly reason approach in this case IMHO!)
I don't like they are forced to know about ICommandLogger (which they
do not use).
Well they do; unless you instantiate an object of type ICommandLogger in the abstract class and provide a parameterless constructor, you're currently forcing inheritors to know about it.

Categories

Resources