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

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.

Related

Refactor with strategy pattern and then apply SOLID principle

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.

Changing IRepository to support IQueryable (LINQtoSQL queries)

I've inherited a system that uses the Castle Windsor IRepository pattern to abstract away from the DAL which is LinqToSQL.
The main problem that I can see, is that IRepository only implements IEnumerable. So even the simplest of queries have to load ALL the data from the datatable, to return a single object.
Current usage is as follows
using (IUnitOfWork context2 = IocServiceFactory.Resolve<IUnitOfWork>())
{
KpiFormDocumentEntry entry = context2.GetRepository<KpiFormDocumentEntry>().FindById(id, KpiFormDocumentEntry.LoadOptions.FormItem);
And this uses lambda to filter, like so
public static KpiFormDocumentEntry FindById(this IRepository<KpiFormDocumentEntry> source, int id, KpiFormDocumentEntry.LoadOptions loadOptions)
{
return source.Where( qi => qi.Id == id ).LoadWith( loadOptions ).FirstOrDefault();
}
So it becomes a nice extension method.
My Question is, how can I use this same Interface/pattern etc. but also implement IQueryable to properly support LinqToSQL and get some serious performance improvements?
The current implementation/Interfaces for IRepository are as follows
public interface IRepository<T> : IEnumerable<T> where T : class
{
void Add(T entity);
void AddMany(IEnumerable<T> entities);
void Delete(T entity);
void DeleteMany(IEnumerable<T> entities);
IEnumerable<T> All();
IEnumerable<T> Find(Func<T, bool> predicate);
T FindFirst(Func<T, bool> predicate);
}
and then this is implemented by an SqlClientRepository like so
public sealed class SqlClientRepository<T> : IRepository<T> where T : class
{
private readonly Table<T> _source;
internal SqlClientRepository(Table<T> source)
{
if( source == null ) throw new ArgumentNullException( "source", Gratte.Aurora.SHlib.labelText("All_TableIsNull",1) );
_source = source;
}
//removed add delete etc
public IEnumerable<T> All()
{
return _source;
}
public IEnumerator<T> GetEnumerator()
{
return _source.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
The problem at the moment is, in our example above, the .Where is calling 'GetEnumerator', which then loads all rows into memory, and then looks for the one we need.
If I change IRepository to implement IQueryable, I can't implement the three methods needed, as these are not public in the Table class.
I think I should change the SQLClientRepository to be defined like so
public sealed class SqlClientRepository<T> : IQueryable<T>, IRepository<T> where T : class
And then implement the necessary methods, but I can't figure out how to pass the expressions around etc. as they are private members of the Table class, like so
public override Type ElementType
{
get { return _source.ElementType; } //Won't work as ElementType is private
}
public override Expression Expression
{
get { return _source.Expression; } //Won't work as Expression is private
}
public override IQueryProvider Provider
{
get { return _source.Provider; } //Won't work as Provider is private
}
Any help really appreciated to move this from 'iterate through every row in the database after loading it' to 'select x where id=1'!
If you want to expose linq you can stop using the repository pattern and use Linq2Sql directly. The reason to this is that every Linq To Sql provider has it's own custom solutions. So if you expose LINQ you get a leaky abstraction. There is no point in using an abstraction layer then.
Instead of exposing LINQ you got two options:
Implement the specification pattern
Use the repository pattern as I describe here: http://blog.gauffin.org/2013/01/repository-pattern-done-right/
So, while it may not be a true abstraction any longer, the main point was to get the benefit of linq to sql without updating all the queries already written.
so, I made the IRepository implement IQueryable instead of IEnumerable.
then in the SqlClientRepository implementation, I can call AsQueryable() to cast the Table to IQueryable, and then all is good, like so.
Now everywhere somebody has written IRepository().Where(qi => qi.id = id) or similar, it actually passes the ID to sql server and only pulls back one record, instead of all of them, and loops through looking for the correct one.
/// <summary>Provides the ability to query and access entities within a SQL Server data store.</summary>
/// <typeparam name="T">The type of entity in the repository.</typeparam>
public sealed class SqlClientRepository<T> : IRepository<T> where T : class
{
private readonly Table<T> _source;
private readonly IQueryable<T> _sourceQuery;
IQueryable<T> Query()
{
return (IQueryable<T>)_source;
}
public Type ElementType
{
get { return _sourceQuery.GetType(); }
}
public Expression Expression
{
get { return _sourceQuery.Expression; }
}
public IQueryProvider Provider
{
get { return _sourceQuery.Provider; }
}
/// <summary>Initializes a new instance of the <see cref="SqlClientRepository{T}"/> class.</summary>
/// <param name="source">A <see cref="Table{T}"/> to a collection representing the entities from a SQL Server data store.</param>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is a <c>null</c> reference (<c>Nothing</c> in Visual Basic).</exception>
internal SqlClientRepository(Table<T> source)
{
if( source == null ) throw new ArgumentNullException( "source", "All_TableIsNull" ) );
_source = source;
_sourceQuery = _source.AsQueryable();
}

Is it possible to obtain instance of component being resolved before satisfying property dependency?

public class A
{
public X x { get; set; }
}
public class B
{
public X x { get; set; }
}
public class X
{
public X(object owner) { /* ... */ }
}
Basically if classes A and B are registered in Windsor I want to be able to resolve X dependency in such a way that it gets instance of the class it was required for.
In plain code it would look like that:
var a = new A();
var x = new X(a);
a.X = x;
Is there a way to do this in Windsor, maybe through some extensibility mechanism?
It looks like some crazy question even for me, so here is some motivation behind it:
The X in the example above is ITracer which is a proxy for TraceSource that is adding some bits of info to each traced message, namely, unique ID of the owner and its type (now it is only ID - that's why the question - I can't get to the instance and call GetType() on it).
A brief example to make it more clear. Suppose you have some service IService and want to add traces to it in the most non-intrusive way. But in the application could be dozen of instances of this service, so in traces you want to distinguish them by ID/type. It would be good if class received its tracer from the container and just wrote messages there when needed, without thinking of IDs, concrete TraceSource etc.
I already have some infrastructure that allows me to write like that:
[TracedTo("NameOfTheTraceSource")]
public class Service : IService
{
public ITracer Tracer { get; set; }
}
And Windsor correctly resolves Tracer to be its own (non-shared with other objects) instance of ITracer pointing to TraceSource with name NameOfTheTraceSource. Moreover, if I add traceAllMethods = true to the attribute - Windsor will automatically add interceptor which will write down each method call on this instance via the same Tracer (and only does this if corresponding TraceSource has some listeners configured - we don't have to support adding them on the fly). This is just awesome because it doesn't require anything from the developer of Service and it doesn't suffer performance degradation when it is not needed, not a bit. And so I'm working to make this even more convenient :)
OK, I think what you want here is a facility. Here's a simple one (with no error checking) that may be what you're looking for (or at least point you in the right direction):
public class XFacility : AbstractFacility
{
protected override void Init()
{
this.Kernel.ComponentCreated += KernelOnComponentCreated;
}
private void KernelOnComponentCreated(ComponentModel model, object instance)
{
var props =
instance.GetType().GetProperties().Where(p => p.CanWrite && p.PropertyType == typeof (X));
if (props.Any())
{
var pi = props.First();
pi.SetValue(instance, new X(instance), null);
}
}
}
Now make sure you add the facility to the container before you do any resolving:
var container = new WindsorContainer();
container.AddFacility<XFacility>();
container.Register(Component.For<A>(),
Component.For<B>()
);
var a = container.Resolve<A>();

What control do I have over the TypedFactory Windsor implements?

My colleague set up a Windsor TypedFactoryFacility in our project.
I'm new to Windsor and don't understand how it is implementing the the methods in the IServiceFactory interface we register as a factory. When I saw a Create method that takes a type parameter T and returns a T, I figured that it's probably calling the container's Resolve method under the covers.
I need an overload of Create that takes a Type as a parameter and returns an object. Since the container's Resolve method has both of these flavors:
T Resolve<T>(string key);
object Resolve(Type service);
I thought adding the overload of Create would work. Instead, it appears to be trying to resolve a System.Object instead of the Type I pass in.
Is there a way to make Windsor implement my Create method the way I want it to? I've poked around a bit with reflector, but can't figure it out.
Here is the registration:
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IServiceFactory>()
.AsFactory()
.LifeStyle.Transient);
and the interface itself:
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
//The overload that I need that throws an exception
object Create(Type service)
void Release(object service);
}
Do you want to call something like serviceFactory.Create(typeof(IMyServce)) instead of serviceFactory.Create<IMyService>()?
Try using reflection in an extension method, like this
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType).Invoke(factory, new object[]{});
}
}
EDIT:
This extension method does indeed work with a factory created by Castle Windsor.
Here's my original test code, which you can drop into Program.cs of a VS2010 console application, add a reference to Castle.Core and Castle.Windsor, and run. I used Castle.Windsor 2.5.4.
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace StackOverflow9198461
{
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType)
.Invoke(factory, new object[] { });
}
}
class Program
{
static void Main()
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component
.For<IServiceFactory>()
.AsFactory());
container.Register(Component
.For<IMyService>()
.ImplementedBy<MyService>()
.LifeStyle.Singleton);
var factory = container.Resolve<IServiceFactory>();
var s1 = factory.Create<IMyService>();
var s2 = factory.Create(typeof(IMyService));
Console.WriteLine(s1.GetType().FullName);
Console.WriteLine(s2.GetType().FullName);
if (s1 == s2) Console.WriteLine("Success");
}
}
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
////The overload that I need that throws an exception
//object Create(Type service)
void Release(object service);
}
public class MyService : IMyService
{
}
public interface IMyService
{
}
}

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.