HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Autowiring publishers/listeners with reflection in Unity Framework

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
reflectionunitywithlistenerspublishersautowiringframework

Problem

I'm currently building an application with the Microsoft Unity Framework. I also use a simple system of message publishers/listeners inspired from MVVM light and caliburn:

The listener interface

public interface IMessageListener
{

    void Handle(T Message);
}


The messenger interface

public interface IMessagePublisher
{

    void Subscribe(IMessageListener subscriber);

    void Unsubscribe(IMessageListener subscriber);

    void Publish(T message);
}


I started to find it boring to have to inject my messengers to my listeners so they can subscribe, so I thought: "Hey, my Unity container can do that". I've coded a UnityExtension which autowires all resolved listener objects with their appropriate messenger(s) by using reflection. Of course, my messengers are ContainerLifeTimeManaged.

```
public override void PostBuildUp(IBuilderContext context)
{
base.PostBuildUp(context);

foreach (Type interf in context.Existing.GetType().GetInterfaces().Where(i => i.IsGenericType))
{
//If the interface is of type IMessageListener
if (interf.GetGenericTypeDefinition() == typeof(IMessageListener).GetGenericTypeDefinition())
{
//Get the generic parameter type
Type genericParameter = interf.GetGenericArguments().FirstOrDefault();
//Build the messenger type
Type messengerType = typeof(IMessagePublisher).GetGenericTypeDefinition().MakeGenericType(genericParameter);
//Resolve the messenger
object messenger = _container.Resolve(messengerType);
//Find the subscribe method
MethodInfo subscribeMethod = messenger.GetType().GetMethod("Subscribe");
//Subscribe the listener (the array is ugly, but i just keep getting an error without it)
subscribeMethod.Invoke(messenger, new []{

Solution

typeof(IMessageListener).GetGenericTypeDefinition()


You can simplify this to just:

typeof(IMessageListener<>)


Why are you combing Where() with an if? I would stick with one or the other.

interf.GetGenericArguments().FirstOrDefault()


Don't use OrDefault when you're not going to deal with the null. That way, when an error happens, you're going to get a descriptive exception right away, instead of a confusing NullReferenceException later.

If this is part of the exception handling that you removed, then that makes it hard to review your code properly.

// […] the array is ugly, but i just keep getting an error without it


You have to use an array here, MethodInfo.Invoke() is not a params method.

Code Snippets

typeof(IMessageListener<object>).GetGenericTypeDefinition()
typeof(IMessageListener<>)
interf.GetGenericArguments().FirstOrDefault()
// […] the array is ugly, but i just keep getting an error without it

Context

StackExchange Code Review Q#65197, answer score: 3

Revisions (0)

No revisions yet.