Refactor with strategy pattern and then apply SOLID principle - solid-principles

I have a C# class like below in an app, and looking at ways to refactor it.
The Send method does not exist in the class. This is the solution that I came up with.
There will be more email types in the future.
I don't know whether I can apply the SOLID Open/Closed principle here because adding a new emailtype require this class to be modified.
The Consumer of this service should not be concerned about the business logic, but just to know only the new emailType and the customerId. The consumer of the EmailService knows only what type of email to be sent and the customerId.
class EmailService
{
Send(int emailType, int customerId)
{
switch(emailType)
{
case 1: SendSignupEmail(customerId);
break;
case 2: SendOrderEmail(customerId);
break;
case 3: SendCancellationEmail(customerId);
break;
}
}
SendSignupEmail(int customerId);
SendOrderEmail(int customerId);
SendCancellationEmail(int customerId);
}

Strategy pattern requires you to encapsulate BEHAVIORS in order to keep your classes atomic and designed for a single purpose.
What you should do is (I'll write it in Java, but must be very very similar in C#):
interface Message {
void send(int customerId);
}
class SignupMessage implements Message {
// here you implement send method with specifics of signup behavior
}
class OrderMessage implements Message {
// here you implement send method with order specifics
}
class CancellationMessage implements Message {
// here you implement send method with cancellation specifics
}
class EmailService
{
void send(Message message, int customerId) {
message.send(customerId);
}
}
One can also argue that sending logic (connecting to POP server and sending mail) is not related to message itself. Code that remains generic should not be reimplemented, so I think this version makes a lot more sense:
interface Message {
void getMessage(int customerId);
// I've assumed only messages are different between message types
}
// other classes are the same as above (only implementing "getMessage" this time)
class EmailService {
void send(Message message, int customerId) {
string msg = message->getMessage(customerId);
// what follows next is logic to send bessage
}
}

You can replace the switch with a Dictionary and some configuration external to the class:
Define a new interface that represents the signature of the send methods:
interface ISendEmail
{
Send(int customerId);
}
For each send method, create a class that represents the send method.
class SendSignupEmail : ISendEmail
{
public Send(int customerId){}
}
class SendOrderEmail : ISendEmail
{
public Send(int customerId){}
}
class SendCancellationEmail : ISendEmail
{
public Send(int customerId){}
}
These are the email strategies.
Now EmailService can become only a means by which emailTypes are routed to the correct implementation, and it need never change for new emailTypes (OCP).
public interface IEmailService
{
void Send(int emailType, int customerId);
}
class EmailService : IEmailService
{
private readonly Dictionary<int, SendEmail> senders = new Dictionary<int, SendEmail>();
public Send(int emailType, int customerId)
{
SendEmail email;
if (senders.TryGetValue(emailType, out email)) //replaces the switch
{ //found the email type, delegate the sending to the registered instance
email.Send(customerId);
}
else
{
//unregistered email type, this is like a default case in a switch
}
}
public Register(int emailType, SendEmail sender)
{
senders.Add(emailType, sender);
}
}
Then at one point in your system you can create this service and register the email implementations:
var emailService = new EmailService();
emailService.Register(1, new SendSignupEmail());
emailService.Register(2, new SendOrderEmail());
emailService.Register(3, new SendCancellationEmail());
IEmailService iEmailService = emailService;
You should reuse this implementation and pass the same instance to the clients (DIP) as an IEmailService. Use of the interface here is ISP, because they do not require (and must not use) the classes Register method.
So as you can see, a new email implementation will just be a new class and a new registration line, achieving OCP:
emailService.Register(4, new SendSomeNewEmail(serviceItDependsOn));
Notice serviceItDependsOn, because I am using DIP I can inject extra services, or maybe an email template. Lots of additional complexity required by a new email can be handled without modifying either the client or EmailService.
This differs from usual examples of strategy pattern because of the routing to the correct strategy, but it is still externalizing the work behind an interface and the strategy implementations are supplied to the class. I think those are the key components so I would still classify this as the strategy pattern.

Related

how to mock "this" of a class using powermock or mockito

Class that i want to mock:
TestClass.java
public class testClass(){
public String getDescription(String input){
String value = this.getDetails(input); // i am not going to change this line, hence want to mock this.
//below this i have some complexity logic, which i would like to fix cyclomatic complexity issue
}
private String getDetails(String input){
return "More details for the "+input;
}
}
My questions is how do i mock "this.getDetails(input)" to return some string for testing purpose?
If you've got a class that is big and complex enough that you need to mock a small piece of it, take that as a hint that you're violating the Single Responsibility Principle and properly split up the classes. If you use dependency injection, you can then supply whatever implementation you'd like.
public class TestClass {
/**
* Computes a detail string based on an input. Supply this in the constructor
* for full DI, relax visibility, or add a setter.
*/
private final Function<String, String> detailFunction;
public String getDescription(String input){
String value = detailFunction.apply(input);
// ...
}
}
As a lightweight alternative, you can test an override or spy of your actual class.
#Test public void testTestClassWithOverride() {
TestClass instanceUnderTest = new TestClass() {
#Override public String getDescription(String input) {
return "Predictable value";
}
};
// test your instanceUnderTest here
}
#Test public void testTestClassWithSpy() {
TestClass spyUnderTest = Mockito.spy(new TestClass());
doReturn("Predictable value").when(spyUnderTest).getDescription(anyString());
// test your spyUnderTest here
}
Bear in mind that, though this is an option for you, it shouldn't be your first option: Rather than testing your actual class, you're testing a one-off variant of it, and you've made it so other consumers can subclass your TestClass as well. If possible, write the flexibility you need into the class itself and treat your test as a consumer that plays by the same rules.
First of all, it is a bad practice to make a so-called "partials mocks". This illustrates that your code doesn't follow single responsibility principle that leads to your code being not (or hardly) testable.
I would suggest you to extract getDescription method from your class and use it indirectly via dependency inversion or more concrete - dependency injection (for instance by employing Spring Framework):
public class TestClass() {
private DetailsServiceProvider detailsServiceProvider;
public TestClass(DetailsServiceProvider detailsServiceProvider) {
this.detailsServiceProvider = detailsServiceProvider;
}
public String getDescription(String input) {
String value = detailsServiceProvider.getDetails(input); // i am not going to change this line, hence want to mock this.
//below this i have some complexity logic, which i would like to fix cyclomatic complexity issue
}
}
public interface DetailsServiceProvider {
String getDetails(String input);
}
public class DetailsServiceProviderImpl implements DetailsServiceProvider{
#Override
public String getDetails(String input) {
return "More details for the "+input;
}
}
Then in your test, you could simply:
#Test
public void test() {
DetailsServiceProvider mockedProvider = Mockito.mock(DetailsServiceProvider.class);
//TODO: add scenarios for the mocked object
TestClass target = new TestClass(mockedProvider);
String description = target.getDescription();
//TODO: add assertions
}
If you do not want to struggle with the preferred approach you could use #Spy in Mockito. This will create exactly what you want - a partial mock for your object where part of the methods will be real and another part - mocks:
#Test
public void test() {
TestClass partialMockedObject = Mockito.spy(new TestClass());
Mockito.doReturn("test details").when(partialMockedObject).getDetails();
String description = partialMockedObject.getDescription();
//TODO: add assertions
}
Again, this method is not desired but can be used if no other options are given. Note that this requires getDetails() to be visible in tests, meaning that the private modifier won't work here.

Castle Windsor: A better way to implement 2 levels of (nested) factories?

We have a pattern we've used several times, whereby we implement handlers and factories in separate Dlls. We configure exe's at runtime saying what dlls are loaded, and therefore what handlers are available to the app.
We do this because we have custom handling for some customers, also it allows great flexibility because we can quickly develop new handlers in isolation, and test and deploy them with confidence that we haven't even touched any other parts of a running application. We can also patch handlers by simply dropping in a single replacement dll, we have customers with strict change management procedures and they adore this.
To do this the pattern relies on two levels of factories, specific factories that implement specific handlers, and an overarching factory (which we call a Provider). The Provider chooses which handler factory to use to create a handler.
The question: Does Windsor contain something that would simplify this process for us?
Specifically I'm looking for something that could omit the Handler factory objects, it feels like something it should be able to do.
I've read up on the Typed Factory Facility and the UsingFactory & UsingFactoryMethod methods, but I can't see how they'd be any help here.
That said I often find the Castle Windsor documentation obtuse so I could be missing something obvious
Or is there just a better way of getting the same end goal that I haven't considered.
Here's some code to illustrate, first message, handler and factory interfaces
public interface IMessage
{
string MessageType { get; }
}
public interface IMessageHandler
{
void Process(IMessage message);
}
public interface IMessageHandlerFactory
{
bool CanProcessType(string type);
IMessageHandler Create();
}
In a second DLL we implement a handler and factory for Type1
public class Type1MessageHandler
: IMessageHandler
{
public void Process(IMessage message) { }
}
public class Type1MessageHandlerFactory
: IMessageHandlerFactory
{
public bool CanProcessType(string type)
{
return type == "Type1";
}
public IMessageHandler Create()
{
return new Type1MessageHandler();
}
}
In a third Dll we implement a handler and factory for Type2
public class Type2MessageHandler
: IMessageHandler
{
public void Process(IMessage message) { }
}
public class Type2MessageHandlerFactory
: IMessageHandlerFactory
{
public bool CanProcessType(string type)
{
return type == "Type2";
}
public IMessageHandler Create()
{
return new Type2MessageHandler();
}
}
In a windows service we implement the provider
public interface IMessageHandlerProvider
{
IMessageHandler Create(string messageType);
}
public class MessageHandlerProvider
: IMessageHandlerProvider
{
IEnumerable<IMessageHandlerFactory> factories;
public MessageHandlerProvider(IWindsorContainer wc)
{
factories = wc.ResolveAll<IMessageHandlerFactory>();
}
public IMessageHandler Create(string messageType)
{
foreach (var factory in factories)
if (factory.CanProcessType(messageType))
return factory.Create();
throw new UnableToFindMessageHandlerFactoryForType(messageType);
}
}
The service that actually needs the handlers only uses the Provider
public class MessageService
{
public MessageService(IMessageHandlerProvider handlerProvider) {}
}
What you are asking is indeed possible in Windsor with typed factories; instead of resolving all the factories in your provider and then looking for the ones that can process the message, you could ask Windsor for the handler that is linked to the message type and just use it. You don't really need the second level factory (IMessageHandlerFactory), because the handler can tell what message it will link to.
Here is a nice resource for this architecture (you've probably read this one already) which I'll summarize very quickly.
Given your interfaces, you start by registering all your handlers
container.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IMessageHandler>()
.WithServiceAllInterfaces());
Ok, now let's tell Windsor we want a factory that will return a IMessageHandler. What is nice is that we don't actually have to code anything for the factory.
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IMessageHandlerProvider>().AsFactory());
Now we can start using the factory
var provider = container.Resolve<IMessageHandlerProvider>();
var msg = new Type2Message();
var msgHandler = provider.Create(msg.MessageType);
The problem is that since there is no link between our message handlers and the string we pass to the factory, Windsor returns the first registered instance of a IMessageHandler it finds. In order to create this link we can name each message handler after the message type it is supposed to handle.
You can do it in a variety of ways, but I like to create a convention where a message handler type tells what messages it can handle:
container.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IMessageHandler>()
.WithServiceAllInterfaces().Configure(c => {
c.Named(c.Implementation.Name.Replace("MessageHandler", string.Empty));
}));
Now you need to tell your factory that the message type must be used as the name of the handler you want to resolve. To do that, it is possible to use a class inheriting the DefaulTypedFactoryComponentSelector. We just override the way component names are determined and return the message type we are receiving:
public class MessageHandlerSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return arguments[0].ToString();
}
}
Now we can plug this selector in the factory
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IMessageHandlerProvider>()
.AsFactory(c =>c.SelectedWith(new MessageHandlerSelector())));
Here is the full code to handle any messages:
var container = new WindsorContainer();
container.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IMessageHandler>()
.WithServiceAllInterfaces().Configure(c => {
c.Named(c.Implementation.Name.Replace("MessageHandler", string.Empty));
}));
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IMessageHandlerProvider>().AsFactory(c =>c.SelectedWith(new MessageHandlerSelector())));
var provider = container.Resolve<IMessageHandlerProvider>();
var msg = new Type2Message();
var msgHandler = provider.Create(msg.MessageType);
msgHandler.Process(msg);
Here are some points I would like to underline:
as you guessed, you don't need the two factories: one is enough
the naming convention for the message handlers is not set in stone, and you could decide to have another mechanism in place to override the convention
I am not talking about releasing the components, but the links contain some info about it which you should look into
I didn't handle the case where no handler can be found, but Castle will throw by itself when it cannot resolve the handler with a ComponentNotFoundException
The system could perhaps be more robust if the handlers were explicit about the message types they handle. For example changing the interface to IHandlerOf<T> with T being a message type implementation.

Custom types in Navigation parameters in v3

In v3 if I wanted to pass two objects to another viewmodel:
public class Dog
{
}
public class Cat
{
}
var dog = new Dog();
var cat = new Cat();
ShowViewModel<SomeViewModel>(new {Dog = dog, Cat = cat });
public class SomeViewModel
{
Init(Dog dog, Cat cat)
{
}
}
As far as I can tell that won't work because the types aren't recognized and can't be stuck in a dictionary. If I wanted to have these serialized as json, passed to the view model, and deserialized as Init parameters, would I implement IExtraParser? And if that is correct, how do I go about adding the implementations to the ExtraParsers dictionary?
update:
This seems to do it:
var foo = Mvx.Resolve<IMvxFillableStringToTypeParser>();
foo.ExtraParsers.Add(new MyParser());
The default navigation mechanism in MvvmCross is deliberately lightweight.
It is really there to allow you to pass just one simple, serializable object - e.g.
public class DogNav
{
public int Id {get;set;}
public string Caption {get;set;}
}
// received in:
public class DogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
}
With this setup, if a navigation is triggered like:
// navigation
ShowViewModel<DogViewModel>(new DogNav() { Id=12, Caption="Good boy" });
then the underlying system will transport the values from that DogNav object - possibly using Uris, Intents or other serialization techniques - to the new DogViewModel and will then ensure Init is called with the correct values.
Because of the serialization, it's important:
not to pass big objects (Uris on WindowsPhone can break above a few hundred characters)
not to expect the same object instance to arrive - i.e. if you are using database-backed or stateful objects, then it's best to pass some kind of lookup key rather than the objects themselves.
not to expect that only one ViewModel will receive the message - on some operating systems, it may be that the user goes back and forth many, many times between apps causing many Views and ViewModels to be created.
not to expect that a ViewModel that receives the message is in the same process and memory space as the ViewModel that sent the request - the same may actually be received days later after a tombstoning event.
If you do want to pass multiple objects via navigation, then I think you can do this using code like:
public class CatNav
{
public int CatId {get;set;}
public string CatCaption {get;set;}
}
public class DogNav
{
public int DogId {get;set;}
public string DogCaption {get;set;}
}
// received in:
public class CatAndDogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
public void Init(CatNav catNav)
{
}
}
In this case you could navigate using:
var catNav = new CatNav() { CatId =12, CatCaption="Meow" };
var dogNav = new DogNav() { DogId =12, DogCaption="Woof" };
var bundle = new MvxBundle();
bundle.Write(catNav);
bundle.Write(dogNav);
ShowViewModel<CatAndDogViewModel>(bundle);
I think this would work...
However... please be aware that the serialization is very simple - so if CatNav and DogNav were to share a property name, then this would lead to problems - you'd end up with some Cags and Dots
Because of the Cag and Dot problem I don't recommend this approach...
If you do need more complex transitions in your apps, then one route is to:
UPDATE - see Passing complex navigation parameters with MvvmCross ShowViewModel
1. Add the Json Plugin (or any Json serializer) and change your Setup.cs code to create a MvxJsonNavigationSerializer - overriding CreateNavigationSerializer
protected override IMvxNavigationSerializer CreateNavigationSerializer()
{
return new MvxJsonNavigationSerializer();
}
Use a composite object in navigation like:
public class DogAndCatNav
{
public DogNav DogNav {get;set;}
public CatNav CatNav {get;set;}
}
This would be received by:
public void Init(DogAndCatNav dogAndCatNav)
{
}
But note that this technique does need a more powerful serialization engine - such as Json.
Overall... even after writing all this... I'd recommend you pass as little data as possible in your navigations!

Intercepting explicit interface implementations with Castle Dynamic Proxy

I am having trouble getting Castle Dynamic Proxy to intercept methods that are explicit interface implementations. I read here http://kozmic.pl/category/dynamicproxy/ that it should be possible to do this.
Here are my classes;
internal interface IDomainInterface
{
string DomainMethod();
}
public class DomainClass : IDomainInterface
{
string IDomainInterface.DomainMethod()
{
return "not intercepted";
}
}
Here is my interceptor class;
public class DomainClassInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.Name == "DomainMethod")
invocation.ReturnValue = "intercepted";
else
invocation.Proceed();
}
}
And here is my test (which fails);
[TestClass]
public void can_intercept_explicit_interface_implementation()
{
// Create proxy
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), interceptor);
// Invoke proxy method
var result = proxy.DomainMethod();
// Check method was intercepted -- fails
Assert.AreEqual("intercepted", result);
}
In addition to not being able to intercept the explicit interface implementation, it also seems that I am not receiving a notification of a non-proxyable member.
Here is my proxy generation hook (which acts as a spy);
public class DomainClassProxyGenerationHook : IProxyGenerationHook
{
public int NonProxyableCount;
public void MethodsInspected() {}
public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
{
NonProxyableCount++;
}
public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
{
return true;
}
}
Here is my test (which again fails);
[TestMethod]
public void receive_notification_of_nonproxyable_explicit_interface_implementation()
{
// Create proxy with generation hook
var hook = new DomainClassProxyGenerationHook();
var options = new ProxyGenerationOptions(hook);
var generator = new ProxyGenerator();
var interceptor = new DomainClassInterceptor();
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), options, interceptor);
// Check that non-proxyable member notification was received -- fails
Assert.IsTrue(hook.NonProxyableCount > 0);
}
Has anyone had success in getting DP to intercept explicit interface implementations? If so, how?
You are creating a class proxy. Class proxy only intercepts virtual methods on the class, and an explicit implementation of an interface method in C# by definition is not virtual (since it's private).
If you want to intercept methods on the interface you need to explicitly tell DynamicProxy about it
var proxy = (IDomainInterface)generator.CreateClassProxy(typeof(DomainClass), new Type[] { typeof(IDomainInterface) }, interceptor);
Also your interface is marked as internal so made sure it's public for DynamicProxy (either make the interface public or add InternalsVisibleToAttribute).
With that your first test will pass, and the method will be intercepted.

LINQ to SQL validate all fields, not just stop at first failed field

I just started using LINQ to SQL classes, and really like how this helps me write readable code.
In the documentation, typical examples state that to do custom validation, you create a partial class as so::
partial class Customer
{
partial void OnCustomerIDChanging(string value)
{
if (value=="BADVALUE") throw new NotImplementedException("CustomerID Invalid");
}
}
And similarly for other fields...
And then in the codebehind, i put something like this to display the error message and keep the user on same page so to correct the mistake.
public void CustomerListView_OnItemInserted(object sender, ListViewInsertedEventArgs e)
{
string errorString = "";
if (e.Exception != null)
{
e.KeepInInsertMode = true;
errorString += e.Exception.Message;
e.ExceptionHandled = true;
}
else errorString += "Successfully inserted Customer Data" + "\n";
errorMessage.Text = errorString;
}
Okay, that's easy, but then it stops validating the rest of the fields as soon as the first Exception is thrown!! Mean if the user made mode than one mistake, she/he/it will only be notified of the first error.
Is there another way to check all the input and show the errors in each ?
Any suggestions appreciated, thanks.
This looks like a job for the Enterprise Library Validation Application Block (VAB). VAB has been designed to return all errors. Besides this, it doesn't thrown an exception, so you can simply ask it to validate the type for you.
When you decide to use the VAB, I advise you to -not- use the OnXXXChanging and OnValidate methods of LINQ to SQL. It's best to override the SubmitChange(ConflictMode) method on the DataContext class to call into VAB's validation API. This keeps your validation logic out of your business entities, which keeps your entities clean.
Look at the following example:
public partial class NorthwindDataContext
{
public ValidationResult[] Validate()
{
return invalidResults = (
from entity in this.GetChangedEntities()
let type = entity.GetType()
let validator = ValidationFactory.CreateValidator(type)
let results = validator.Validate(entity)
where !results.IsValid
from result in results
select result).ToArray();
}
public override void SubmitChanges(ConflictMode failureMode)
{
ValidationResult[] this.Validate();
if (invalidResults.Length > 0)
{
// You should define this exception type
throw new ValidationException(invalidResults);
}
base.SubmitChanges(failureMode);
}
private IEnumerable<object> GetChangedEntities()
{
ChangeSet changes = this.GetChangeSet();
return changes.Inserts.Concat(changes.Updates);
}
}
[Serializable]
public class ValidationException : Exception
{
public ValidationException(IEnumerable<ValidationResult> results)
: base("There are validation errors.")
{
this.Results = new ReadOnlyCollection<ValidationResult>(
results.ToArray());
}
public ReadOnlyCollection<ValidationResult> Results
{
get; private set;
}
}
Calling the Validate() method will return a collection of all errors, but rather than calling Validate(), I'd simply call SubmitChanges() when you're ready to persist. SubmitChanges() will now check for errors and throw an exception when one of the entities is invalid. Because the list of errors is sent to the ValidationException, you can iterate over the errors higher up the call stack, and present them to the user, as follows:
try
{
db.SubmitChanges();
}
catch (ValidationException vex)
{
ShowErrors(vex.ValidationErrors);
}
private static void ShowErrors(IEnumerable<ValidationResult> errors)
{
foreach(var error in errors)
{
Console.WriteLine("{0}: {1}", error.Key, error.message);
}
}
When you use this approach you make sure that your entities are always validated before saving them to the database
Here is a good article that explains how to integrate VAB with LINQ to SQL. You should definitely read it if you want to use VAB with LINQ to SQL.
Not with LINQ. Presumably you would validate the input before giving it to LINQ.
What you're seeing is natural behaviour with exceptions.
I figured it out. Instead of throwing an exception at first failed validation, i store an error message in a class with static variable. to do this, i extend the DataContext class like this::
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Summary description for SalesClassesDataContext
/// </summary>
public partial class SalesClassesDataContext
{
public class ErrorBox
{
private static List<string> Messages = new List<string>();
public void addMessage(string message)
{
Messages.Add(message);
}
public List<string> getMessages()
{
return Messages;
}
}
}
in the classes corresponding to each table, i would inherit the newly defined class like this::
public partial class Customer : SalesClassesDataContext.ErrorBox
only in the function OnValidate i would throw an exception in case the number of errors is not 0. Hence not attempting to insert, and keeping the user on same input page, without loosing the data they entered.