StartableFacilityRegistrationExtensions
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel.Registration;
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Castle.Facilities.Startable
{
public static class StartableFacilityRegistrationExtensions
{
public static ComponentRegistration<TService> Start<TService>(this ComponentRegistration<TService> registration) where TService : class
{
return registration.AddAttributeDescriptor("startable", true.ToString());
}
public static ComponentRegistration<TService> StartUsingMethod<TService>(this ComponentRegistration<TService> registration, string startMethod) where TService : class
{
return registration.Start().AddAttributeDescriptor("startMethod", startMethod);
}
public static ComponentRegistration<TService> StartUsingMethod<TService>(this ComponentRegistration<TService> registration, Expression<Func<TService, Action>> methodToUse) where TService : class
{
string value = ObtainMethodName(methodToUse);
return registration.Start().AddAttributeDescriptor("startMethod", value);
}
public static ComponentRegistration<TService> StopUsingMethod<TService>(this ComponentRegistration<TService> registration, string stopMethod) where TService : class
{
return registration.Start().AddAttributeDescriptor("stopMethod", stopMethod);
}
public static ComponentRegistration<TService> StopUsingMethod<TService>(this ComponentRegistration<TService> registration, Expression<Func<TService, Action>> methodToUse) where TService : class
{
string value = ObtainMethodName(methodToUse);
return registration.Start().AddAttributeDescriptor("stopMethod", value);
}
private static TExpression EnsureIs<TExpression>(Expression expression) where TExpression : Expression
{
TExpression val = expression as TExpression;
if (val == null)
throw new FacilityException("Unexpected shape of expression. Expected direct call to method, something like 'x => x.Foo'");
return val;
}
private static string ObtainMethodName<TService>(Expression<Func<TService, Action>> methodToUse)
{
UnaryExpression unaryExpression = EnsureIs<UnaryExpression>(methodToUse.Body);
MethodCallExpression methodCallExpression = EnsureIs<MethodCallExpression>(unaryExpression.Operand);
ConstantExpression constantExpression = EnsureIs<ConstantExpression>(methodCallExpression.Arguments[2]);
return ((MethodInfo)constantExpression.Value).Name;
}
}
}