Variation on Service Locator - c#

IModificationRequst<Employee> req = new ModificationRequst();
Locator.Instance.GetService<IModificationRequstHandler<Employee>>().Handle(req);
I have a service locator that locates services that returns instances of objects implementing IModificationRequstHandler.
I am trying to modify it to rather than returning a IModificationRequstHandler implementer, it is just internally finds the service and invokes it's handler method, so the above 2 lines would look like this instead:
IModificationRequst<Employee> req = new ModificationRequst();
Locator.Instance.HandleRequest<IModificationRequst<Employee>>(req);
But having hard time with the generics, is there an already established pattern for resovling the requests to their proper request handlers and invoking their handling, rather than getting a handler and then invoking their Handle method from the client?

That violates Single Responsibility Principle. You should not make the service locator implement logic for different services.
If you do want to use static classes you should add another one:
public static class RequestHandler
{
public static void Handle<T>(T request)
{
Locator.Instance.GetService<IModificationRequstHandler<T>>().Handle(req);
}
}
And then:
IModificationRequst<Employee> req = new ModificationRequst();
RequestHandler.Handle(req);
(Sidenote: You might look up Dependency Injection & IoC containers since it makes the code more maintainable)

Your HandleRequest method in the locator class should be defined as follows (assuming Handle has a return type of void):
public void HandleRequest<T>(IModificationRequest<T> req)
{
IModificationRequstHandler<T> handler = GetService<IModificationRequest<T>>();
handler.Handle(req);
}
and your IModificationRequstHandler interface should be defined as follows:
public interface IModificationRequstHandler<T>
{
void Handle(IModificationRequst<T> req);
}
and your call will then become:
Locator.Instance.HandleRequest(req);
The generic type parameter Employee here is inferred from the parameter value req and thus does not need to be specified.

Related

Decorator pattern to create a type

Can the decorator pattern be used to create / build a type?
For example, lets say we want to hydrate an object. Arguably we can have a builder class that does it all but what if its a complex object with multiple layers, is it valid to have multiple decorators that hydrate a portion of that object and return it back to the caller?
For instance:
For instance we have FirstDecorator which calls an API and the result we instantiate the type and hydrate parts of it. Because this was a successful call, we will invoke the next decorator.
SecondDecorator then invokes an API but hydrates another aspect of the object.
I like this approach because I can have multiple decorators that hydrate a specific portion of the object and easily be extended by simply adding another decorator to the sequence.
The problem here is with definition and is this leaning towards Chain of Responsibility (CoR)? My understanding is that CoR allows you to terminate the chain at anytime and not allow the other processors to act. Decorator pattern implies that all must be executed? The difference between the two is very sketchy to me.
The chain-of-responsibility pattern is structurally nearly identical
to the decorator pattern, the difference being that for the decorator,
all classes handle the request, while for the chain of responsibility,
exactly one of the classes in the chain handles the request. This is a
strict definition of the Responsibility concept in the GoF book.
However, many implementations (such as loggers below, or UI event
handling, or servlet filters in Java, etc) allow several elements in
the chain to take responsibility.
The code example I have:
public interface IPokemonDecorator
{
// Every decorator will hydrate a part of PokeApiResponse
Task Decorate(PokeApiResponse pokeApiResponse, PokeRequest request);
}
public class BasicInfoDecorator
{
private readonly IPokemonDecorator _pokemonDecorator;
private readonly IPokemonApiAdapter _pokemonApiAdapter;
public BasicInfoDecorator(
IPokemonDecorator pokemonDecorator,
IPokemonApiAdapter pokemonApiAdapter)
{
_pokemonDecorator = pokemonDecorator;
_pokemonApiAdapter = pokemonApiAdapter;
}
public async Task Decorate(PokeApiResponse pokeApiResponse, PokeRequest request)
{
var httpResponse = await _pokemonApiAdapter.Execute($"api/v2/pokemon/{request.Name}", request);
pokeApiResponse = await httpResponse.Content.ReadFromJsonAsync<PokeApiResponse>();
if (pokeApiResponse != null)
{
request.Id = pokeApiResponse.Id.ToString();
await _pokemonDecorator.Decorate(pokeApiResponse, request);
}
}
}
public class DetailedInfoDecorator
{
private readonly PokeApiAdapter _pokemonApiAdapter;
public DetailedInfoDecorator(PokeApiAdapter pokemonApiAdapter)
{
_pokemonApiAdapter = pokemonApiAdapter;
}
public async Task Decorate(PokeApiResponse pokeApiResponse, PokeRequest request)
{
var httpResponse = await _pokemonApiAdapter.Execute($"api/v2/pokemon-species/{request.Id}", request);
var details = await httpResponse.Content.ReadFromJsonAsync<SpeciesDetails>();
pokeApiResponse.SpeciesDetails = GetDescriptionOrDefault(request, details);
}
private static SpeciesDetails GetDescriptionOrDefault(PokeRequest request, SpeciesDetails speciesDetails)
{
// some logic to get description based on default language or requested language
throw new NotImplementedException();
}
}
Arguably can do the same using an application service that orchestrates the calls and gets the responses and then passes it to a builder to construct the object.
Is this a violation of the principle?

c# .Net Core DI: Request from ServiceProvider a implementation of a generic interface where the generic property is only known at runtime

I have following issue:
I'm working on a system which processes various Types of "Events" which all trigger a different business logic (called EventProcessor in this example). The code is now refactored to a point where I now want one generic "Eventprocessor" which is able to, dependent on the ingested event type, returns the correct Businesslogic to process this event.
public class GenericEventProcessor
{
private IServiceProvider _serviceProvider { get; }
public GenericEventProcessor(IServiceProvider serviceProvider)
{
this._serviceProvider = serviceProvider;
}
public Task RunAsync(string eventCarrierString, ILogger log, string functionName)
{
var eventCarrier = JsonConvert.DeserializeObject<EventCarrier>(eventCarrierString);
Type eventType= typeof(eventCarrier.EventType);
var eventProcessor =_serviceProvider.GetService(IEventProcessor<eventType>)
eventProcessor.RunAsync(eventCarrier.eventString, log, functionName)
}
}
The event is passed in as a "EventCarrier" Object which has two properties,
-A Enum telling which type of Event this is,
-And another string which contains the actual event.
The actual business logic is implemented in various EventProcessors which implement a IEventProcessor Interface, where T is some Event.
This apparently does not work (because i can't pass the eventType into the Generic Interface) and i have the feeling that i'm doing this completly wrong.
What would you suggest to implement something like this? (Or get this to run!)
Thanks in advance,
Matthias
Try to use MakeGenericType to build required type at runtime
Type eventType= typeof(eventCarrier.EventType);
Type processor = typeof(IEventProcessor<>);
Type generic = processor.MakeGenericType(eventType);
var eventProcessor =_serviceProvider.GetService(generic);

Nested call don't trigger interceptors

I want to attach interceptor to a few methods, from which one of them might call other intercepted methods, only the fist interceptor is run. How can I get this to work:
class A : IWorker
{
int Method1()
{
return 2*Method2();
}
int Method2()
{
return 5;
}
}
Interceptor implementation
public class WorkerUsageLogger : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var indent = new string('\t', tabs);
Console.WriteLine($"{indent}Calling method {invocation.Method.Name}.");
tabs++;
invocation.Proceed();
tabs--;
Console.WriteLine($"{indent}Completed method {invocation.Method.Name}");
}
}
attaching interceptor
var builder = new ContainerBuilder();
builder.RegisterInstance(new WorkerUsageLogger());
builder.RegisterType<A>().As<IWorker>().EnableInterfaceInterceptors().InterceptedBy(typeof(WorkerUsageLogger));
var container = builder.Build();
IWorker worker = container.Resolve<IWorker>();
On calling
worker.Method1();
I'm expecting:
"Calling method Method1"
"Calling method Method2"
"Completed method Method2"
"Completed method Method1"
I'm getting
"Calling method Method1"
"Completed method Method1"
The interceptor returns an object of type IWorker, which has code to go through your interceptor, which performs logging. Nothing actually edits the code in class A to intercept, perform logging, etc. Since said code calls methods in the same A class, ie this, the interceptor you've injected into the IWorker call is never touched during those nested calls.
To observe this, try printing worker.GetType() (or observing the type in a debugger) and note that it will not be of type A.
This can be an example of the Single Responsibility Principle, in that your interface implementations should not be calling things on the this object because it can break down logging and unit testing. If you can't digest your solution into separate interfaces, you might consider making your implementation request a property of the same interface type and calling on that.

How to discover the underlying Implementation Type of a decorated instance when calling GetAllInstances?

I have this code:
using (container.BeginLifetimeScope())
{
RenderWord instruction = new RenderWord();
var instances = container.GetAllInstances<IInstructionHandler<RenderWord>>();
var firstInstance = result.First();
}
instances is of type IEnumerable<IInstructionHandler<RenderWord>>
firstInstance is of type IInstructionHandler<RenderWord> that in reality is an instance of a decorator that decorates another decorator that decorates another decorator ...
At runtime the actual class instances is of type ContainerControlledCollection<IInstructionHandler<RenderWord>> and this ContainerControlledCollection class holds a very useful piece of information - the underlying ImplementationType.
Is there any way for me to get to the ContainerControlledCollection or the producers[0].Value.ImplementationType at runtime because I’d really like to be able to discover the base implementation type underneath the chain of decorators.
I think #atomaras might have a good point about your abstraction, although I think it would be fine when you only use this information inside your Composition Root, since your Composition Root is already aware of every implementation in the system.
I think there are a few ways to get to this information:
Use the DecoratorPredicateContext information that is supplied to the RegisterDecorator extension method:
var typeMapping = new Dictionary<Type, Type>();
container.RegisterDecorator(typeof(IInstructionHandler<>), typeof(FakeDecorator<>), c =>
{
typeMapping[c.ServiceType] = c.ImplementationType;
// or perhaps even use c.AppliedDecorators property to see which decorators
// are applied.
// return false to prevent the decorator from being applied.
return false;
});
You can make a fake registration that Simple Injector will call for every IInstructionHandler<T> in the system, but you prevent it from being applied by supplying a predicate that will always return false. You can use the info supplied by Simple Injector in the DecoratorPredicateContext to find out what the actual ImplementationType is.
Alternatively, you can inject an DecoratorContext instance (v2.6 and up) into the top most decorator (as explained here). The DecoratorContext contains the same information as the DecoratorPredicateContext does, but this object will automatically be injected by Simple Injector into a decorator that depends on. It allows you to make the decision inside a decorator, which might be very convenient in your case.
Add an an IDecorator abstraction to the system to allow traversing the decorator chain.
By letting each decorator implement a IDecorator interface that allows access to the decoratee (just as done here) you can traverse the decorator chain and find the actual implementation type:
public interface IDecorator
{
object Decoratee { get; }
}
public static class DecoratorHelpers
{
public static IEnumerable<object> GetDecoratorChain(IDecorator decorator)
{
while (decorator != null)
{
yield return decorator;
decorator = decorator.Decoratee as IDecorator;
}
}
}
You can implement your decorators with this interface as follows:
public class SomeDecorator<T> : IInstructionHandler<T>, IDecorator
{
private readonly IInstructionHandler<T> decoratee;
public SomeDecorator(IInstructionHandler<T> decoratee)
{
this.decoratee = decoratee;
}
object IDecorator.Decoratee { get { return this.decoratee; } }
}
When you implemented this interface on all your decorators, you will be able to do this:
var implementationTypes =
from handler in container.GetAllInstances<IInstructionHandler<RenderWord>>()
let mostInnerDecorator =
DecoratorHelpers.GetDecoratorChain(handler as IDecorator).LastOrDefault()
let implementation = mostInnerDecorator != null ? mostInnerDecorator.Decoratee : handler
select implementation.GetType()
Register a list of Registration instances in one of the RegisterAll overloads, since the Registration object knows about the actual implemenation type.
But instead of point 3, you might as well use the list of implemenation types that you used to create those registrations:
typeMapping[serviceType] = implementationTypes;
container.RegisterAll(serviceType, implementationTypes);
Simple Injector will resolve the registered implementations always in the same order as they are registered (this is guaranteed). So when you resolve a collection of things, you will already have the list of implementations that is layed out in the same order.
Why dont you just check the type of the firstInstance? Wouldn't that give you the actual implementation type?
I have to say though that the fact that you need to know the implementation type is a good indication of problems with your abstraction.

InheritanceBasedAopConfigurer using runtime constructor arguments

I've got a (prototype) class owned by the Spring.NET context, created with an AutoProxy with runtime constructor arguments. It get's instantiated like this.
var context = ContextRegistry.GetContext();
var myClass = context.GetObject("myclass", new object[]{ myRuntimeConstructorArgument }) as MyClass;
This class has some inner logic going, where it catches an event that gets handled by a class method, like this:
// MyClass owned by Spring.NET context
public class MyClass {
// InnerObject not owned by Spring context
private InnerObject innerobject;
// argument object not owned by Spring context
public MyClass(ObjectNotOwnedBySpring myRuntimeConstructorArgument) {
...
this.innerobject = new InnerObject();
this.innerobject.SomeEvent += this.handleSomeEvent;
}
// I would like to intercept this event handler
public virtual void handleMyEvent (object sender, EventArgs args)
{
// do stuff
}
}
I'm trying to use AOP to remove an abstraction leak (caused by a bug in an external component), by intercepting the handleMyEvent method. Because Spring.Aop uses a proxy based approach to intercept method calls, inner method calls don't get intercepted. I get that part.
If I understand the documentation correctly, that's where the InheritanceBasedAopConfigurer comes into play, by using a 'true' inheritance based AOP mechanism. From the documentation:
Interception advice is added directly in the method body before invoking the base class method.
Exactly what I need!
Unfortunatly, I can't get the InheritanceBasedAopConfigurer get to play nicely with the runtime constructor arguments:
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'myclass' > defined in 'file [spring-aop-config.xml] line 36' : Could not resolve matching constructor.
Is runtime constructor arguments not supported by the InheritanceBasedAopConfigurer ? Or is this a wrong use case for the InheritanceBasedAopConfigurer ?

Categories

Resources