views:

82

answers:

1

I have these registrations in a registry and am trying to figure out the correct way to implement them with a scanner instead of manual registration.

For<ISomeView>.Use(HttpContext.Current.CurrentHandler)
For<IOtherView>.Use(HttpContext.Current.CurrentHandler)
For<IAnotherView>.Use(HttpContext.Current.CurrentHandler)

And so on. I have ever one of my interfaces inherent from IView to be used as a marker interface.

My original attempt came out looking like this

public void Process(Type type, Registry registry)
{
    Type _pluginType = typeof(IView);

    if (type.CanBeCastTo(_pluginType) && type.IsInterface)
    {
        string name = type.Name;
        registry.AddType(_pluginType, type, name);

        registry.For(_pluginType).Use(HttpContext.Current.CurrentHandler);
    }    
} 

This however caused my physical ASP.NET pages to be registered as itself instead. This is what I got from WhatDoIHave()

the_page_aspx (ASP.the_page_aspx) - 36d0cdb2-7118-4a1d-94a0-8de1b5ddc357 - 
Configured Instance of ASP.the_page_aspx, App_Web_4q8pukge, Version...

Edit: To respond to KevM's comment what I want to acheive is anytime StructureMap needs to inject any single of my IView's that it resolves it by by returning HttpContext.Current.CurrentHandler

So if I'd call ObjectFactory.Resolve<ISomeView>() I would get (ISomeView)HttpContext.Current.CurrentHandler

If I have a constructor that was SomePresenter(IListView listView, IEditView editView) that those would be resolved to (IListView)HttpContext.Current.CurrentHandler and (IEditView)HttpContext.Current.CurrentHandler.

I could do this with numerous For<>.Use() statements as in my example which means I should be able to achieve it with a scanner instead of needing to explicitly register each one manually. My interfaces will always be named I___View if the naming convention would help for writing the scanner. I'm just not sure what I need to use in the if statement I have above for the Process() method.

Update: With the answer from @KevM it pointed me in the right direction to this

public class ViewScanner : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        if (type.IsA<IView>() && !type.IsConcrete())
        {
            registry.For(type).Use(c => HttpContext.Current.CurrentHandler);
        }
    }
}

(IsA<> is just an extension for IsAssignableFrom since to me the usage of it feels backwards)

+1  A: 

I hope this is close to what you are looking for.

public interface IView { }
public class View : IView { }
public class View2 : IView { }

public static class IckyStaticMonster
{
    public static IView Current { get; set;}
}

[TestFixture]
public class configuring_concrete_types
{
    [Test]
    public void TEST()
    {
        var container = new Container(cfg =>
        {
            cfg.Scan(scan =>
            {
                scan.TheCallingAssembly();
                scan.Convention<ViewScanner>();
            });
        });

        var current = new View2();
        IckyStaticMonster.Current = current;

        var view2 = container.GetInstance<View2>();

        view2.ShouldBeTheSameAs(current);
    }
}

public class ViewScanner : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        Type _pluginType = typeof (IView);

        if (_pluginType.IsAssignableFrom(type) && _pluginType.IsInterface)
        {
            registry.For(type).Use(c=>IckyStaticMonster.Current);
        }
    }
}
KevM
This looks like what I'm trying to do I'll have to test it out and I'll let you know!
Chris Marisic
This was almost it but your answer gave me the info I needed.
Chris Marisic
Glad to help. I have to give some credit to Josh Flanagan he helped too.
KevM