Orchard-like events

Intro

Once I have worked with Orchard CMS. Orchard has well implemented features. One of most liked by me is event system.

How it works?

Consider I have interface that represents some events:

interface IUserEvent : IEvent
{
  void Created(string id);
  void Updated(string id);
}

So let’s create some handlers:

class LogUserEvents : IUserEvent
{
  public void Create(string id)
  {
    someLogger.Log($"User { id } created");
  }

  public void Updated(string id)
  {
    someLogger.Log($"User { id } updated");
  }
}

And usage

class SomeService
{
    private readonly IUserEvents userEvents;
    
    public SomeService(IUserEvents userEvents)
    {
      this.userEvents = userEvents;
    }
}

And… that’s all! The Event bus system automatically searches for implementations, resolves it with the current dependency resolver and calls proper methods. Magic!

How Can I achieve it?

The first step is to create a proxy class for interfaces, that automatically invokes all implementations. I have used Castle.DynamicProxy for it:

public class MultiInterfaceProxy : IInterceptor
{
    private readonly Lazy<IEnumerable<IEvent>> events;

    private MultiInterfaceProxy(Type eventType, 
                                IImplementationProvider implementationProvider)
    {
        this.events = implementationProvider.For(eventType);
    }

    private IEnumerable<IEvent> Events
    {
        get { return this.events.Value; }
    }

    public static object For(Type eventType, 
                            IImplementationProvider implementationProvider)
    {
        if (!eventType.IsInterface)
            throw new ArgumentException("Event must be an interface.", "eventType");

        if (!typeof(IEvent).IsAssignableFrom(eventType))
            throw new ArgumentException("Event must be derrived from IEvent", "eventType");

        var generator = new ProxyGenerator();
        var proxtInterceptor =
            new MultiInterfaceProxy(eventType,
                                    implementationProvider);

        return generator.CreateInterfaceProxyWithoutTarget(eventType, proxtInterceptor);
    }


    public void Intercept(IInvocation invocation)
    {
        var returnType = invocation.Method.ReturnType;

        if (returnType.IsGenericType &&
            typeof(IEnumerable<>).IsAssignableFrom(returnType.GetGenericTypeDefinition()))
        {
            this.InvokeWithEnumerableReturn(invocation, returnType);
        }
        else if (returnType == typeof (Task))
        {
            this.HandleTask(invocation);
        }
        else
        {
            this.InvokeVoid(invocation);
        }
    }

    private void HandleTask(IInvocation invocation)
    {
        var tasks = this.Events.Select(ev => (Task) invocation.Method.Invoke(ev,
            invocation.Arguments)).ToArray();


        invocation.ReturnValue = Task.Factory.StartNew(() => Task.WaitAll(tasks));
    }

    private void InvokeVoid(IInvocation invocation)
    {
        object result = null;

        foreach (var @event in this.Events)
        {
            try
            {
                result = invocation.Method.Invoke(@event, invocation.Arguments);
            }
            catch (Exception ex)
            {
                HandleException(ex, @event);
            }
        }

        invocation.ReturnValue = result;
    }

    private void InvokeWithEnumerableReturn(IInvocation invocation, 
                                            Type returnType)
    {
        var list =
            (IList)
            Activator.CreateInstance(typeof(List<>)
            .MakeGenericType(returnType.GetGenericArguments()[0]));

        foreach (var @event in this.Events)
        {
            try
            {
                var enumerable = (IEnumerable)invocation.Method.Invoke(@event, invocation.Arguments);
                if (enumerable == null)
                {
                    continue;
                }

                var enumerator = enumerable.GetEnumerator();

                while (enumerator.MoveNext())
                {
                    list.Add(enumerator.Current);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex, @event);
            }
        }

        invocation.ReturnValue = list;
    }

    private static void HandleException(Exception ex, IEvent proxiedEvent)
    {
        if (!(ex is TargetInvocationException))
        {
            throw ex;
        }

        var tex = ex.InnerException;
        if (tex == null)
        {
            throw ex;
        }

        if (!(tex is EventFatalException) && !proxiedEvent.IsAlwaysFatal())
        {
            return;
        }

        if (tex.InnerException != null)
        {
            tex = tex.InnerException;
        }

        throw tex;
    }
}

(part of classes are skipped).

But alone proxy is not enough - we need to integrate it with some dependency injection library. I have chosen my favourite - AutoFac:

foreach (var eventType in this.GetAllEventTypes())
{
    var localEventType = eventType;
    var eventTypeKey = new object();

    builder.RegisterAssemblyTypes(this.assemblies)
           .AssignableTo(localEventType)
           .As(localEventType)
           .InstancePerLifetimeScope()
           .Keyed(eventTypeKey, eventType);

    builder.Register(ctx => MultiInterfaceProxy.For(localEventType,
                                                    new ComponentContextProvider(ctx, eventTypeKey)))
           .As(localEventType).InstancePerLifetimeScope();
}

What do you think about it?

Full code available on github.

ContinueWith - real case sample

On the previous episode…

Lastly, I have written about ContinueWith. Now it is time to show real case.

Case

Consider API;

public Task<IEnumerable<Foo>> GetFoos()
{
    return context.Foos.ToListAsync();
}

This won’t compile - Task<List<Foo>> cannot be casted into Task<IEnumerable<Foo>>. So how to handle it without introducing await/async?

public Task<IEnumerable<Foo>> GetFoos()
{
    return context.Foos.ToListAsync()
                       .ContinueWith(task => task.Result.AsEnumerable());
}

Object-type based flow

After spending lots of hours on Stackoverflow site, I have found some questions about control flow based on instance type. For example:

How can simplify that snippet? Is this the only way?

object obj = GetObject();
if (obj is MyClass)
{
  var casted = obj as MyClass;
  // actions
}

if (obj is OtherClass)
{
  var casted = obj as OtherClass;
  // actions
}

First of all - If you have such a situation - your design of architecture is bad. I’m almost sure that problem can be solved by changing structure of your classes.

I’m stubborn / I don’t want to change my class design / I just want to know the answer

Dynamic feature

You can use dynamic (introduced in C# 4.0):

void MyAction(MyClass class)
{
}

void MyAction(OtherClass)
{
}

object obj = GetObject();
MyAction((dynamic)obj);

How does it work? Dynamic forces to resolve type at runtime, so proper overload will be chosen. Main drawback? If you forget to prepare overload for type, you will get runtime binder-exception.

Generic invoker

To get benefit from dynamic and if approach I have prepared small library with Fluent API:

object obj = GetObject();
obj.DetermineType().When((MyClass target) => { /* action */ })
                   .When((OtherClass target) => { /* action */ })
                   .WhenMissing(_ => { /* action */ })
                   .Resolve();

c# 7.0 - possible solution

There is feature proposal for C# 7.0 called Declaration Expressions:

if (var myClass = obj as MyClass) 
{
    //use myClass here
}

It was planned feature for C# 6.0, but was finally cut-out.

ContinueWith - is it worth?

Case

So far, I have had plenty of similar snippets:

public async Task<string> GetSomePropertyAsync()
{
    return (await GetAsync()).MyProperty;
}

To prevent additional task creation we can do the following:

public Task<string> GetSomePropertyAsync()
{
    return GetAsync().ContinueWith(task => task.Result.MyProperty);
}

According to this article it is faster.

Another thing - the exception handling in both cases is different - here is a nice post about it.

Trap

So it is worth to get rid of async/await everywhere? Yes, but you should keep in mind some consequences:

public Task Foo()
{
    using (var myDisposable = GetSomeDisposable())
    {
         return DoSomeTask();
    }
}

public async Task Foo()
{
    using (var myDisposable = GetSomeDisposable())
    {
         return await DoSomeTask();
    }
}

In the first case - myDisposable is disposed as soon as the task is created - but no necessarily completed.

In the second snippet - myDisposable is disposed after stuff in DoSomeTask() is completed.

Bad lazy loading

What happend?

I have the following classes with many-to-many relation:

public class Customer 
{
     public HashSet<Invoice> Invoices { get; set; }
}

public class Invoice
{
     public HashSet<Customer> Customers { get; set; }
}

Now, I would like to add existing invoice to the customer:

Invoice inv = new Invoice
    {
        Id = 10
    };

dbContext.Invoices.Attach(inv);
someCustomer.Invoices.Add(inv);

When try to run the snippet written above, the following exception is thrown:

Cannot insert duplicate key into ‘dbo.CustomerInvoices’….

What is the problem?

After spending a couple of minutes on searching solution, it turned out that remedy is very simple:

public class Customer 
{
     public virtual HashSet<Invoice> Invoices { get; set; }
}

Yes, virtual word was the key. Without it, EF is not able to track changes. But why such an error was thrown? Do not know, maybe you guys?

Coroutines exception handling

What is wrong

If you are developing with Unity 3D, coroutines are part of your life. Exceptions are also. It sounds trivial, but it is not easy to bring together both of these things. Consider:

1 public IEnumerable SomeCoroutine()
2 {
3     yield return foo;
4     yield return bar;
5 }

One of the natural ways to handle general exception is to surround it with try..catch:

1 public IEnumerable SomeCoroutine()
2 {
3    try {
4         yield return foo;
5         ...
6         yield return bar;
7         ....
8    } catch { ... }
9 }

Looks nice, right?

No, it doesn’t. It won’t even compile. We need to get rid of yield from block to get it to work:

 1 public IEnumerable SomeCoroutine()
 2 {
 3 
 4    yield return foo;
 5 
 6    try {
 7      ...
 8    } catch { ... }
 9 
10    yield return bar;
11 
12    try {
13      ...
14    } catch { ... }
15 }

Shit, not what I looked for…

Solution

In order to handle this strange case I have created a wrapper

 1 public class CoroutineExceptionCatcher : IEnumerator
 2 {
 3     private readonly IEnumerator wrapped;
 4     private readonly Action<Exception> handler;
 5 
 6     public CoroutineExceptionCatcher(IEnumerator wrapped, Action<Exception> handler)
 7     {
 8         this.wrapped = wrapped;
 9         this.handler = handler;
10     }
11 
12     public bool MoveNext()
13     {
14 
15         try
16         {
17             return this.wrapped.MoveNext();
18         }
19         catch (Exception ex)
20         {
21             if (this.handler == null) throw ex;
22 
23             this.handler(ex);
24             return false;
25         }
26     }
27 
28     public void Reset()
29     {
30         this.wrapped.Reset();
31     }
32 
33     public object Current
34     {
35         get { return this.wrapped.Current; }
36     }
37 }

Usage is very simple:

1 StartCoroutine(new CoroutineExceptionCatcher(
2       MyCoroutine().GetEnumerator(),
3       exception =>
4             {
5                  Debug.LogError(
6                  "Fatal error: " + exception.Message
7                    + ", stacktrase: " + exception.StackTrace);
8             }));

Nice, right?

Syncthing Web UI - The beginnig

Background

In a previous blog I have written about my mini-PC that was setup as the server. I have decided to move everything from OneDrive (my OneDrive space was limited from 30 Gb to 7 due to last Microsft rule changes) The most known self-hosted solution is ownCloud. Written in PHP, easy to install - it just fits requirements. Unfortunately, it turned out that the newest version has no Windows support (via FastCGI).

After digging somewhere on the internet I have found syncthing. It offers an alternative approach. There is no central server - everything is based on distributed sharing. Dedicated client for windows (client app is server itself), easy install. So what is the problem? Imagine the situation, when you are at friend’s home. You need to download the file from your cloud. A friend didn’t know about syncthing before. So you need to download the app, allow new client to “join” your devices network and viola. There is no web client that could be very use full in some scenarios.

I could not find any 3rd solutions that could offer some PHP-or-whatever site to integrate with the new cloud. But wait. I’m a programmer!

Syncting Web UI

Syncthing Web UI is web app that reads metadata from syncthing config file and offers basic functionality as web client:

  • Watching syncthing config file changes
  • Reading folders content
  • Downloading files & folders
  • Sharing files
  • Users management (with folders permissions)

Some nice screenshots:

Setup

Dashboard

Files

Sharing

You can find more about project on GitHub.

Hello World!

Welcome back!

Welcome to my new blog. As you can remember, the old one was setup for DajSięPoznać contest. A quality of posts was low (sic!) so I decided to start from the scratch. No posts will be moved (unless I find some time) but believe me - there is no good content to read ;)

Current blog was setup with jekyll so speed of page load should be like a thunder. How do you like a dbyll theme?

See you!