Service Locator easier to use than dependency Injection? - c#

The application I am working on is relying on Autofac as DI container and one of the reasons that made me decide to use it, among others, was the delegate factory feature (see here)
This works fine for all cases where I need to recreate the same elements several times as is the case of some reports and related screens. Some reports (even those of the same type) are executed concurrently but they change only by their user-defined parameters so it makes sense (I think) to inject factories in order to create instances, passing the free parameters and leave the rest to the application.
The problem comes with the fact that each report is made of a variable number of sub reports (tasks) and each task implements an ITask interface. Each report may have up to 50 different tasks to use and each task encapsulates a precise business operation. One option I have is to inject delegate factories for and create them when needed.
These tasks have to be dynamically generated by factories and something like:
var myTaskA = _taskFactoryConcreteTaskA();
var myTaskB = _taskFactoryConcreteTaskB();
var myTaskC = _taskFactoryConcreteTaskC();
...
var myTaskZZ = = _taskFactoryConcreteTaskZZ();
requires a lot of manual wiring (delegates, constructor, backing fields etc) while something like
var myTaskA = _taskFactory.Create<ConcreteTaskA>();
var myTaskB = _taskFactory.Create<ConcreteTaskB>();
var myTaskC = _taskFactory.Create<ConcreteTaskC>();
...
var myTaskZZ = _taskFactory.Create<ConcreteTaskZZ>();
would be incredibly less work especially if the _taskFactory wraps the container as shown in this other post, but also it would basically mean I am using a service locator to create my tasks.
What other options do I have that may be suitable to solve this?
(NOTE: there is a good chance I am completely off track and that I have to read a lot more about DI, in which case any contribution would be even more important)

Since the factories indicated in the question don't take any arguments, using a factory smells of a Leaky Abstraction. As Nicholas Blumhardt points out in his answer, a better approach might be to simply inject each task into the consumer.
In this case, since all the tasks implement the same interface, instead of injecting up to 50 different ITask instances, you can compose them:
public class MyConsumer
{
private readonly IEnumerable<ITask> tasks;
public MyConsumer(IEnumerable<ITask> tasks)
{
this.tasks = tasks;
}
public void DoSomething()
{
foreach (var t in this.tasks)
{
// Do something with each t
}
}
}
Alternatively, you can compose the sequence of ITasks into a Composite, which is actually my preferred solution:
public CompositeTask : ITask
{
private readonly IEnumerable<ITask> tasks;
public CompositeTask(IEnumerable<ITask> tasks)
{
this.tasks = tasks;
}
// Implement ITask by iterating over this.tasks
}
This would simplify the consumer and turn the fact that there are more than one task to be performed into an implementation detail:
public class MyConsumer
{
private readonly ITask task;
public MyConsumer(ITask task)
{
this.task = task;
}
public void DoSomething()
{
// Do something with this.task
}
}

One approach worth investigating is to break the problem into'units of work' that use a set of related tasks:
public class WorkItem1 : ISomeWork
{
public WorkItem1(Task1 t1, Task2 t2...) { }
public void DoSomething() { ... }
}
Then, your use of factories would come down towards someWorkFactory().DoSomething(), possibly for a few different kinds of 'something'.
A class having a large number of dependencies, on factories or anything else, usually points to there being smaller, more focused classes waiting to be discovered to break up the work.
Hope this helps.

Related

How can I avoid God Class anti-pattern on this design

I think I designed my app focusing all the logic in one single class (A). I have been reading that is not a good practise to do this. Class A have a lot of nested logic, each method of Solve() uses as input the result of the previous ones. I dont know if I should create separate classes for DoTask1, DoTask2, DoTask3 and DoTask4, and instantiate them from Solve(). Would that be better? I know I can also create separate classes with static methods but I have read that too many static methods are bad.
Main()
{
A a = new A()
a.Solve()
}
A()
{
Solve()
{
partialresult1 = DoTask1()
partialresult2 = DoTask2(partialresult1)
partialresult3 = DoTask3(partialresult2)
finalresult = DoTask4(partialresult3)
}
DoTask1(){}
DoTask2(){}
DoTask3()
{
B b = new B()
b.doWathever()
}
DoTask4(){}
}
B()
{
doWhatever(){}
}
It is difficult to know without the full extent of the problem but I'll take a guess and make a suggestion.
You have different payloads and based on them, you want to apply different tasks.
I would, at first create the ITask interface:
public interface ITask {
Result DoWork(PartialResult res);
}
Now you can create task classes that can do some part of the work. The client could create the list and execute accordingly.
public Task1: ITask {
public Result DoWork(PartialResult res) {
// some work here
}
}
Now as an extra, you could use the AbstractFactory design pattern. Each abstract factory implementation, will create the list of tasks needed for a specific job. The client can the use them to execute the payload.
Those two solutions will probably make your super class obsolete
For more information on the AbstractFactory design pattern, check: https://refactoring.guru/design-patterns/abstract-factory

Detecting that a method is called without a lock

Is there any way to detect that a certain method in my code is called without using any lock in any of the methods below in the call stack?
The goal is to debug a faulty application and find out if certain pieces of code aren't thread safe.
This seems like a decent use case for AOP (aspect oriented programming). A very basic summary of AOP is that its a method of dealing with cross cutting concerns to make code dry and modular. The idea is that if you're doing something to every method call on an object (eg. logging each call) instead of adding a log at the start and end of each method you instead you inherit the object and do that outside of the class as to not muddy its purpose.
This can be done a few ways and I'll give you an example of two. First is manually (this isn't great but can be done very easily for small casses).
Assume you have a class, Doer with two methods Do and Other. You can inherit from that and make
public class Doer
{
public virtual void Do()
{
//do stuff.
}
public virtual void Other()
{
//do stuff.
}
}
public class AspectDoer : Doer
{
public override void Do()
{
LogCall("Do");
base.Do();
}
public override void Other()
{
LogCall("Other");
base.Other();
}
private void LogCall(string method)
{
//Record call
}
}
This is great if you only care about one class but quickly becomes unfeasible if you have to do it for many classes. For those cases I'd recommend using something like the CastleProxy library. This is a library which dynamically creates a proxy to wrap any class you want. In combination with an IOC you can easily wrap every service in your application.
Here's a quick example of using CastleProxy, main points being use ProxyGenerator.GenerateProxy and pass in IInterceptors to do stuff around method calls:
[Test]
public void TestProxy()
{
var generator = new ProxyGenerator();
var proxy = generator.CreateClassProxy<Doer>(new LogInterceptor());
proxy.Do();
Assert.True(_wasCalled);
}
private static bool _wasCalled = false;
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Log(invocation.Method.Name);
invocation.Proceed();
}
private void Log(string name)
{
_wasCalled = true;
}
}
Now, the logging portion. I'm not sure you really NEED this to be lockless, short locks might be enough but lets proceed thinking you do.
I don't know of many tools in C# that support lock free operations but the the simplest version of this I can see is using Interlocked to increment a counter of how many instances are in the method at any given time If would look something like this:
[Test]
public void TestProxy()
{
var generator = new ProxyGenerator();
var proxy = generator.CreateClassProxy<Doer>(new LogInterceptor());
proxy.Do();
Assert.AreEqual(1, _totalDoCount);
}
private static int _currentDoCount = 0;
private static int _totalDoCount = 0;
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "Do")
{
var result = Interlocked.Increment(ref _currentDoCount);
Interlocked.Increment(ref _totalDoCount);
if(result > 1) throw new Exception("thread safe violation");
}
invocation.Proceed();
Interlocked.Decrement(ref _currentDoCount);
}
}
Interlocked uses magical register magic to do thread safe operation (Compare-And-Swap I believe, but I don't really know). If you need more context than just "It Happened". You can use a concurrent stack or a concurrent queue which are lockless (they use interlock as well: https://msdn.microsoft.com/en-us/library/dd997305.aspx/). I would include a timestamp on these though, since I haven't used them enough to know if they promise to return elements in the order they occurred.
Like I said above, you might not NEED lock free operations but this should. I don't know if any of this is a perfect fit for you since I don't know your exact problem but it should provide you some tools to tackle this.
You could host the CLR yourself, and track the locks taken using the IHostSyncManager::CreateMonitorEvent method. You'd then need to expose your own mechanism from your host to your method called say "IsLockTaken()". You could then call that from your method in your actual code.
I think it is possible, but it would be quite a lot of work and almost certainly a complete distraction from the problem you're trying to solve, but no doubt a lot of fun!
Here's an interesting read on Deadlock detection https://blogs.msdn.microsoft.com/sqlclr/2006/07/25/deadlock-detection-in-sql-clr/

How to unit test task from private method

I have a method (some code removed):
try
{
var task = Task.Factory.StartNew(ValidateAccounts, _token);
}
catch (AggregateException)
{
_tokenSource = new CancellationTokenSource();
_token = _tokenSource.Token;
}
ValidateAccounts is a private method withing the same class. I would like to test that it was called and would like to be able to mock the task and try with the exception thrown and without it.
As others have mentioned, you have to be careful when treading the fine line of what-to-test vs. what-not-to-test. It can lead to brittle tests that are too coupled with the implementation.
That being said, I absolutely see the utility in doing what you're trying to do. Testing the exception handling alone is worth asking this question.
The problem is rooted in your use of a static object (Task.Factory). Static objects/methods are notorious for impeding testability. The solution to this problem is the same used for decoupling any type of static object - introducing a seam.
You are using the static object to kick off, and return a reference to, a Task. This is something that you can define a role interface for. It might look something like:
public interface ITaskFactory
{
Task StartNew(Action action);
}
With a production implementation that looks like:
public class TplTaskFactory : ITaskFactory
{
public Task StartNew(Action action)
{
return Task.Factory.StartNew(action);
}
}
You could then use dependency injection to supply your SUT with a mock implementation of this interface, which gives you the capability you're looking for.

Ok not to use all parameters in constructor? - Revisited

This class injects all dependencies in the constructor, but only one of the dependencies are used at a time. Is this considered bad design?
public class OrderPayment
{
ICreditCardPayment _ccPayment;
ICashPayment _cashPayment;
public OrderPayment(ICreditCardPayment ccPayment, ICashPayment cashPayment)
{
_ccPayment = ccPayment;
_cashPayment = cashPayment;
}
private void PrepareOrder(Order order)
{
// Do stuff with the order
}
public PaymentResult PayByCreditCard(Order order)
{
PrepareOrder(order);
return _ccPayment.Pay(order);
}
public PaymentResult PayByCreditCard(Order order)
{
PrepareOrder(order);
return _cashPayment.Pay(order);
}
}
An alternative is this:
public class OrderPayment
{
private void PrepareOrder(Order order)
{
// Do stuff with the order
}
public PaymentResult PayByCreditCard(Order order, ICreditCardPayment ccPayment)
{
PrepareOrder(order);
return ccPayment.Pay(order);
}
public PaymentResult PayByCreditCard(Order order, ICashPayment cashPayment)
{
PrepareOrder(order);
return cashPayment.Pay(order);
}
}
This one complicates the function call somewhat. Would you use the first, cleaner looking one, even though not every constructor parameter is used? Considering a DI framework has to instantiate potentially heavy classes even though they may not all be used, I'm not sure how good this is.
So which one would you use? Or maybe a different implementation?
I would refactor or extract a common interface from ICashPayment and ICreditCardPayment. Your code sample indicates your methods are both invoking xPayment.Pay, which looks like a good candidate for your common interface method.
public interface IPayment
{
PaymentResult Pay(Order order);
}
Your more specialized interfaces can inherit from and build upon it.
In general, I would avoid having constructors (or any method) accept arguments that go unused, or if one argument is used, the other is not. That's normally an indication that you are either not operating at the proper level of abstraction, or that your class/method has too many responsibilities.
You need an operation that requires all of the following:
the payment method
the amount being paid
the order that is being paid for
What processing needs to be done prior to payment, based on the order, and amount being paid
You are trying to define some order of operation independent of what is being performed in the operation. Dependency injection can be used at the method level too.
you need a method like this one:
public PaymentResult Pay(Amount amount, Order order, IOrderService orderService,
IPaymentService paymentService) {
var updatedOrder = orderService.Process(order); // don't alter the original in
// case you need to roll back
var result = paymentService.Pay(amount, updatedOrder);
return result; // this result should include the updated order, so that the system
// can determine what to do upon successful payment
}

Dependency Injection for objects that require parameters

All of our reports are created from object graphs that are translated from our domain objects. To enable this, we have a Translator class for each report, and have been using Dependency Injection for passing in dependencies.
This worked great, and would yield nice classes structured like this:
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc)
{
_empSvc = empSvc;
_paySvc = paySvc;
}
public Check CreateCheck()
{
//do the translation...
}
}
However, in some cases the mapping has many different grouping options. As a result, the c-tor would turn into a mix of class dependencies and parameters.
public class CheckTranslator : ICheckTranslator
{
public CheckTranslator (IEmployeeService empSvc
, IPaycheckService paySvc
, bool doTranslateStubData
, bool doAttachLogo)
{
_empSvc = empSvc;
_paySvc = paySvc;
_doTranslateStubData = doTranslateStubData;
_doAttachLogo = doAttachLogo;
}
public Check CreateCheck()
{
//do the translation...
}
}
Now, we can still test it, but it no longer really works with an IoC container, at least in a clean fashion. Plus, we can no longer call the CreateCheck twice if the settings are different for each check.
While I recognize it's a problem, I don't necessarily see the right solution. It seems kind of strange to create a Factory for each class ... or is this the best way?
Shot in the dark here, but could you move those parameters to the method instead?
In other words:
public Check CreateCheck(bool doTranslateStubData, bool doAttachLogo)
{
//do the translation...
}
Do those parameters have to be passed in via the constructor?
(Note - if your response to this is "there are too many methods for that to be practical", then part of the problem may be that the abstraction is too coarse).
Another option (it's really hard to say without understanding the domain model and injection patterns) would be to introduce a parameter object that is itself managed by the injector:
public interface ICheckConfiguration
{
bool AttachLogo { get; }
bool TranslateStubData { get; }
}
Then inject this with the constructor:
public CheckTranslator (IEmployeeService empSvc, IPaycheckService paySvc,
ICheckConfiguration config)
{
// etc.
}
This should be enough. You can then create a concrete CheckConfiguration class that takes those two bool properties in its constructor, and configure your container to create different instances of the parameter object (interface) based on a higher-level DI parameter.
The last thing I think I should mention is that just because you're using DI doesn't mean that everything has to be managed by the container. It's not such a bad thing to create CheckTranslator objects in an ad-hoc fashion if there's only one kind of "translator". As long as the translator still depends on abstractions, which it does here, then maybe you shouldn't be injecting it at all, just let higher-level DI-enabled classes create them ad-hoc.

Categories