Proper way to use Caliburn Micro with Castle Windsor Interceptor

Topics: Bootstrappers & IoC, Conventions, Getting Started
Nov 10, 2013 at 5:49 AM
I've been trying to get things set up using a Castle Windsor interceptor but it's not getting along with Caliburn Micro. I've tried various solutions I've found here and elsewhere with limited success.

The first hurdle I crossed was that the proxy class created by the interceptor breaks the view / view model naming convention and the view cannot be found. I got past this by overriding ViewLocator.LocateForModelType to give the desired view type, however the property bindings are still broken. Here is a code example, basically a modified version of the original
ViewLocator.LocateForModelType = (modelType, displayLocation, context) =>
    var viewTypeName = modelType.FullName.Replace("Model", string.Empty);

    // brute force it since base type doesn't seem to be working
    if (viewTypeName.StartsWith("Castle.Proxies.I") && viewTypeName.EndsWith("Proxy"))
        viewTypeName = viewTypeName.Replace("Castle.Proxies.I", string.Empty);
        viewTypeName = "MyApp.Views." + viewTypeName.Replace("Proxy", string.Empty);

    if(context != null)
        viewTypeName = viewTypeName.Remove(viewTypeName.Length - 4, 4);
        viewTypeName = viewTypeName + "." + context;

    var viewType = (from assmebly in AssemblySource.Instance
                    from type in assmebly.GetExportedTypes()
                    where type.FullName == viewTypeName
                    select type).FirstOrDefault();

    return viewType == null
        ? new TextBlock { Text = string.Format("*** ERROR *** {0} not found.", viewTypeName), 
            Background = new SolidColorBrush(Colors.Red),
            Foreground = new SolidColorBrush(Colors.White),
            FontWeight = FontWeights.Bold,
            FontSize = 18
        : ViewLocator.GetOrCreateViewType(viewType);
I temporarily overrode HandleUnmatchedElements and sure enough the property bindings are trying to use the proxy class.
ViewModelBinder.HandleUnmatchedElements = (elements, viewModelType) =>
    // breakpoint here
The closest I have gotten is to get the interceptor to intercept, however when it does the property bindings do not work.

There was another method I tried:
var defaultLocator = ViewLocator.LocateTypeForModelType;
ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
    var viewType = defaultLocator(modelType, displayLocation, context);
    while (viewType == null && modelType != typeof(object))
        modelType = modelType.BaseType;
        viewType = defaultLocator(modelType, displayLocation, context);
    return viewType;
However in this case modelType.BaseType was always System.Object so of course it could not resolve to the proper view.

I guess I could keep going through the source but this just doesn't seem like the right path. There has to be a "proper" way to do this?