Return null from typed factory facility

100 views
Skip to first unread message

Kenneth Siewers Møller

unread,
Jan 5, 2012, 6:51:28 AM1/5/12
to castle-pro...@googlegroups.com
Hi,

I'm currently working on an alternative implementation of the TypedFactoryComponentResolver.
My problem is, that I'd like to use typed factories, but I need to return null, in case the component isn't registered.
The concrete usecase is, that I'm looking for a validator for a specific type, and if no validator is registered, it should just return null from the factory.
As the default implementation always throws an exception, if no component is registered, I've created my own version.

/// <summary>
/// Resolves a component. If the component isn't registered, the resolver returns null instead of an exception.
/// </summary>
internal class NullSafeTypedFactoryComponentResolver : TypedFactoryComponentResolver
{
public NullSafeTypedFactoryComponentResolver(string componentName, Type componentType, IDictionary additionalArguments, bool fallbackToResolveByTypeIfNameNotFound, Type actualSelectorType)
: base(componentName, componentType, additionalArguments, fallbackToResolveByTypeIfNameNotFound, actualSelectorType) { }

public override object Resolve(IKernelInternal kernel, IReleasePolicy scope)
{
// Check to see if the component is registered
var hasComponent = componentName != null
? kernel.HasComponent(componentName)
: kernel.HasComponent(componentType);

return hasComponent ? base.Resolve(kernel, scope) : null;
}
}

I'm then overriding the BuildFactoryComponent method from the DefaultTypedFactoryComponentSelector, to return my own implementation.

Since I'm doing something non-standard, I'd just wanted to make sure, I'm not misusing (or misunderstanding) the concept of a typed factory. Basically I'm changing the semantics of the container, so I'm just a bit uncertain about which implications it may bring.


Thanks,
Kenneth

Krzysztof Koźmic

unread,
Jan 5, 2012, 7:37:45 AM1/5/12
to castle-pro...@googlegroups.com
That's not something I would normally recommend but if that's what you want it should be fine :-)

K
--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/castle-project-users/-/GW3SaUL8FTEJ.
To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to castle-project-u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.

Kenneth Siewers Møller

unread,
Jan 5, 2012, 10:02:51 AM1/5/12
to castle-pro...@googlegroups.com
That's exactly why i wrote in the first place :)

I'm not really sure how to approach this then. The point is, that validation is optional. If I should adhere to the open/closed principle, I would think I need only to add a new class to implement the new behavior, correct?

So basically, this is what happens:

When a new message is created, it is passed to the message validation service. The service has a dependency on a IMessageValidatorFactory (typed).
The validation service is calling the factory, passing the message to validate, which in turn is providing a validator for the specific message. If no validator is registered for the message (null), the service should just validate to true.

Am I completely off here and is there a better approach?

Is there a way to return a default for a service, if none is registered that matches the concrete one, like a DefaultMessageValidator?


Kenneth



2012/1/5 Krzysztof Koźmic <krzyszto...@gmail.com>



--
Med venlig hilsen / Kind regards
Kenneth Siewers Møller

Rory Plaire

unread,
Jan 5, 2012, 7:41:08 PM1/5/12
to castle-pro...@googlegroups.com
What about using http://en.wikipedia.org/wiki/Null_Object_pattern for a null validator? Then you don't need to customize the factory and you also don't have to test for null.
 
-r

2012/1/5 Kenneth Siewers Møller <ken...@siewers.dk>

Kenneth Siewers Møller

unread,
Jan 6, 2012, 4:20:44 AM1/6/12
to castle-pro...@googlegroups.com
Yeah, that was what I was thinking about, but how do I return the null object, if what I'm looking for isn't registered?

Kenneth

James Foster

unread,
Jan 6, 2012, 4:54:57 AM1/6/12
to castle-pro...@googlegroups.com
Why not resolve Func<string, IMessageValidator> ? then just place the call inside a try catch.

I may be speaking out of turn since I don't know if this feature exists in Windsor. A quick google search suggests it's possible but you may need to specifically register it, as in:


public class MessageValidationService {
  private Func<string, IMessageValidator> resolver;

  public MessageValidationService(Func<string, IMessageValidator> validatorResolver)
  {
    resolver = validatorResolver
  }

  public bool Validate(IMessage message)
  {
    IMessageValidator validator = null;
    try
    {
      validator = resolver(message.GetType().FullName);
    }
    catch(ComponentNotFoundException)
    {
      validator = resolver(null);
    }

    return validator.Validate(message);
}

2012/1/6 Kenneth Siewers Møller <ken...@siewers.dk>

Rory Plaire

unread,
Jan 6, 2012, 11:02:18 AM1/6/12
to castle-pro...@googlegroups.com
What about always having the null validator registered, and then overriding it as needed?

2012/1/6 Kenneth Siewers Møller <ken...@siewers.dk>
Yeah, that was what I was thinking about, but how do I return the null object, if what I'm looking for isn't registered?

Kenneth Siewers Møller

unread,
Jan 9, 2012, 2:55:26 AM1/9/12
to castle-pro...@googlegroups.com
@James

I generally against try-catch for infrastructure support. I don't believe it should be necessary to do explicit error handling, just to support some needed functionality. That said, your solution is nice, if I just could do it without the try-catch.

@Rory
Yeah, that would be a good idea, but how do I resolve to the null validator, in case the specified validator type doesn't exist? Right now, I'm asking the kernel if it has the component, and if not, it simply returns null.
I guess I could make the component resolver able to return a default instance, but that would make the resolver aware of which components that needs to be registered, which is kind of defeating the point.

There just doesn't seem to be any other existing usecase for this scenario, which leads me to believe I'm doing it wrong.
Reply all
Reply to author
Forward
0 new messages