Skip to content

Instantly share code, notes, and snippets.

@hyrmn
Created March 30, 2011 14:53
Show Gist options
  • Save hyrmn/894547 to your computer and use it in GitHub Desktop.
Save hyrmn/894547 to your computer and use it in GitHub Desktop.
public class HyrmnBlogApplication : TurbineApplication
{
public override void Startup()
{
ServiceLocatorManager.SetLocatorProvider(() => new StructureMapServiceLocator(ObjectFactory.Container));
base.Startup();
}
protected override void ShutdownContext()
{
CurrentContext = null;
ServiceLocator = null;
}
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
}
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily Spark.ISparkSettings, Spark, Version=1.5.0.0, Culture=neutral, PublicKeyToken=7f8549eed921a12c
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: StructureMap.StructureMapException: StructureMap Exception Code: 202
No Default Instance defined for PluginFamily Spark.ISparkSettings, Spark, Version=1.5.0.0, Culture=neutral, PublicKeyToken=7f8549eed921a12c
public class SparkBlade : Blade
{
public override void Spin(IRotorContext context)
{
ViewEngines.Engines.Clear();
var sparkServiceContainer = SparkEngineStarter.CreateContainer();
sparkServiceContainer.AddFilter(new SparkAreasDescriptorFilter());
SparkEngineStarter.RegisterViewEngine(sparkServiceContainer);
var settings = ConfigurationManager.GetSection("spark") as ISparkSettings;
context.ServiceLocator.Register(settings);
}
}
@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011

Here's the fix:

public class DefaultServiceRegistration : IServiceRegistration
{
    public void Register(IServiceLocator locator)
    {
        var container = locator.GetUnderlyingContainer<IContainer>();

        container.Configure(i =>
        {
            i.Scan(a =>
            {
                a.IgnoreStructureMapAttributes();
                a.TheCallingAssembly();
                a.WithDefaultConventions();
            });

            i.For<ISparkSettings>().Use(ConfigurationManager.GetSection("spark") as ISparkSettings);
        });
    }
}

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011

Note, I am still getting some internal exceptions but things are chugging along just fine.... I'll need to bring in the source for SM and Turbine to see as this isn't telling me much. Latest error is:

StructureMap Exception Code: 202
No Default Instance defined for PluginFamily MvcTurbine.ComponentModel.IBinAssemblyLoader, MvcTurbine, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0e426322531bc5b0

at StructureMap.BuildSession.<.ctor>b__0(Type t) in c:\code\structuremap\Source\StructureMap\BuildSession.cs:line 31
at StructureMap.Util.Cache`2.get_Item(KEY key) in c:\code\structuremap\Source\StructureMap\Util\Cache.cs:line 82
at StructureMap.BuildSession.CreateInstance(Type pluginType) in c:\code\structuremap\Source\StructureMap\BuildSession.cs:line 192
at StructureMap.Container.GetInstance(Type pluginType) in c:\code\structuremap\Source\StructureMap\Container.cs:line 265
at StructureMap.Container.GetInstanceT in c:\code\structuremap\Source\StructureMap\Container.cs:line 155
at MvcTurbine.StructureMap.StructureMapServiceLocator.ResolveT

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011

Also...
No Default Instance defined for PluginFamily

MvcTurbine.ComponentModel.IAutoRegistrator, MvcTurbine, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0e426322531bc5b0
System.Web.Mvc.IDependencyResolver, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
System.Web.Mvc.IControllerActivator, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
MvcTurbine.Web.Views.IEmbeddedViewResolver, MvcTurbine.Web, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0e426322531bc5b0

etc...

This is using SM 2.6.2 and mvcturbine.structuremap 3.0

@jglozano
Copy link

ugh, this is why I hate SM at times :) Add a i.For() and set the type to be DefaultBinAssemblyLoader. Note, Turbine always yields to the container - so I query first to see if someone provides X for the implementation, if not, I provide my own.

@jglozano
Copy link

We might have to provide a SM Bootstrapper (IServiceRegistration) for SM specific need...ugh.

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011 via email

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011 via email

@jglozano
Copy link

Ok, a couple of things -

  1. The version we ship with the SM templates is v2.6.1, so I'm not sure what changes occurred between 2.6.2 that would break this. The core pieces for Turbine in v3 have remained untouched (dealing with IBinLoader, blades, etc.). Can you try it with v2.6.2 and see how it behaves?

  2. As for switching to something else, that's completely up to you. I use Windsor/Ninject depending on my needs since I'm not a fan of the way SM handles greedy constructors.

@jglozano
Copy link

Also, when I upgraded Turbine to support MVC3, I didn't change the SM reference. Where are you getting the 2.6.2 from?

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011 via email

@darrencauthon
Copy link

I changed the SM references, along with Windsor and Ninject, to whatever the latest packages were as of two or three nights ago. The included bins looked a little old, and I thought it would be good to refresh and test before putting them up on Nuget.

I'll take a look tonight. There has to be some solution that doesn't require us to bind Turbine to a specific version of StructureMap. That type of solution isn't maintainable in the long-term.

@darrencauthon
Copy link

OT but still good to know: You don't have to go IoC-specific when making those registrations. You can do something similar to what I have below to register concretes. There are also other alternatives to "auto-registration" that could work with any of the containers. If an IoC container is giving me a hassle, I'd just replace it with another until I get a better resolution.

public class DefaultServiceRegistration : IServiceRegistration
{
    public void Register(IServiceLocator locator)
    {
        locator.Register<ISparkSettings>(() => ConfigurationManager.GetSection("spark") as ISparkSettings);
    }
}

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011

Ok... I'm either really using everything wrong or something else is going on.

  1. Downloaded the 3.0 nuget packages from Darren
  2. Set up a local nuget dir, threw them in there, added that dir to VS
  3. Ran the following in a NEW mvc3 solution:

PM> install-package mvcturbine
Successfully installed 'MVCTurbine 3.0'.
Successfully added 'MVCTurbine 3.0' to MvcApplication1.

PM> install-package mvcturbine.ninject
'Ninject (≥ 2.0)' not installed. Attempting to retrieve dependency from source...
Done.
'MVCTurbine 3.0' already installed.
You are downloading Ninject from Ninject Project Contributors, the license agreement to which is available at https://github.com/ninject/ninject/raw/master/LICENSE.txt. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'Ninject 2.2.1.0'.
Successfully installed 'MvcTurbine.Ninject 3.0'.
MvcApplication1 already has a reference to 'MVCTurbine 3.0'.
Successfully added 'Ninject 2.2.1.0' to MvcApplication1.
Successfully added 'MvcTurbine.Ninject 3.0' to MvcApplication1.

  1. Changed global.asax to the following:

namespace MvcApplication1
{
public class MvcApplication : TurbineApplication
{
public override void Startup()
{
ServiceLocatorManager.SetLocatorProvider(() => new NinjectServiceLocator());
base.Startup();
}
}
}

Note... no view engine monkeying... heck, no routes or anything.

Now...

  1. Run:

Error activating IRotorContext
No matching bindings are available, and the type is not self-bindable.
Activation path:

  1. Request for IRotorContext

Suggestions:

  1. Ensure that you have defined a binding for IRotorContext.
  2. If the binding was defined in a module, ensure that the module has been loaded into the kernel.
  3. Ensure you have not accidentally created more than one kernel.
  4. If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
  5. If you are using automatic module loading, ensure the search path and filters are correct.

Same for some other stuff.

@jglozano
Copy link

I don't know what to tell you since well, I didn't test the Ninject stuff.

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011

        ServiceLocatorManager.SetLocatorProvider(() => new WindsorServiceLocator());

Attempt by method 'MvcTurbine.Windsor.WindsorServiceLocator..ctor()' to access method 'MvcTurbine.Windsor.WindsorServiceLocator.CreateContainer()' failed.

@darrencauthon
Copy link

I tested the Ninject stuff, as well as Windsor, StructureMap, and Unity. Enough code to make sure that the metadata stuff worked in each (multiple page hits, posting forms, etc). I even just demoed the StructureMap locator in a presentation less than an hour ago.

The only difference between what you wrote and every MVC Turbine application that I've ever written is that I always set the service locator in the constructor of the TurbineApplication. But I think Startup happens right about then, so I'm not sure yet.

I wish I could help more now, but it will have to be after hours.

@darrencauthon
Copy link

The Windsor one is not working, at least with the nuget package. I emailed Javier about that last night, I'm almost positive that one is a versioning issue.

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011

I did just try wiring up Ninject in the static constructor with the same issue.

public class MvcApplication : TurbineApplication
{
    static MvcApplication()
    {
        // Register the IoC that you want Mvc Turbine to use!
        // Everything else is wired automatically
        ServiceLocatorManager.SetLocatorProvider(() => new NinjectServiceLocator());
    }
}

@darrencauthon
Copy link

You might hate me for this, but I ran your app locally, and....

It worked for me. I see a green site, with talk of you not being a ninja.

I did have to reinstall all of the nuget packages, because the references were broken. Plus, I'm running it under Cassini. I'll switch to IIS Express when I get home.

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011 via email

@hyrmn
Copy link
Author

hyrmn commented Mar 30, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment