tags:

views:

264

answers:

1

I've been using StructureMap for about 6 months now; you would think it would start getting easier. It doesn't seem to.

Here's the first line of my registry:

            For<IDbConnection>()
            .Singleton()
            .Use<SqlConnection>()
            .Ctor<string>(WebConfigurationManager.ConnectionStrings["UnifiedConnectionString"].ConnectionString);

It compiles and runs. But when I try to use that Interface, like this:

            return MsSqlConfiguration.MsSql2008.ConnectionString(((DbConnection)ObjectFactory.GetInstance<IDbConnection>()).ConnectionString);

I get

StructureMap Exception Code:  202
No Default Instance defined for PluginFamily System.Data.IDbConnection, System.Data,
 Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Now I may be missing something (okay, I obviously am), but I don't know how much more plain I can be about defining the default instance for IDbConnection. What am I doing wrong?

Edit: Per Joshua's request, I'm adding full code for a minimal case.

I've tried to create a console app that reproduces the error. It ends up not reproducing it, but giving a different SM exception, which I also don't understand. But maybe when I understand that one, I'll have a clue as to what's going on in the production app.

First, my console app:

       static void Main(string[] args)
    {
        Debug.Print("Connection String: {0}", ConfigurationManager.ConnectionStrings["UnifiedConnectionString"].ConnectionString);
        (new Bootstrapper()).BootstrapStructureMap();

    }

Then, my Bootstrapper module, lifted from the production app:

    public class Bootstrapper : IBootstrapper
{
    public  void BootstrapStructureMap()
    {
        ObjectFactory.Initialize(x =>

                x.Scan(s =>
                {
                    s.WithDefaultConventions();
                    s.TheCallingAssembly();
                    s.LookForRegistries();
                }
                    )
        );
        Debug.Print(ObjectFactory.WhatDoIHave());
        try
        {
            ObjectFactory.AssertConfigurationIsValid();
        }
        catch (StructureMapConfigurationException ex)
        {
            string msg = ex.ToString();
            throw;
        }
        catch (Exception ex)
        {
            string msg = ex.ToString();
            throw;
        }
        InitAutoMapper();
    }

And finally, the DependencyRegistry, lifted from the production app, but with everything beyond the first statement commented out.

    public class DependencyRegistry : Registry
{
    public DependencyRegistry()
    {     
        For<IDbConnection>()
            .Singleton()
            .Use<SqlConnection>()
            .Ctor<string>(ConfigurationManager.ConnectionStrings["UnifiedConnectionString"].ConnectionString);
        //For<...
    }
}

Now what I get when I run this is that it's making it through "WhatDoIHave()", but it's throwing an SM 205 exception on the AssertConfigurationIsValid(). The error (apparently) occurs trying to instantiate SqlConnection, saying "Missing requested Instance property \"connectionString\" for InstanceKey ".

Here's the text of the message:

StructureMap.Exceptions.StructureMapConfigurationException:

Build Error on Instance 'a54d3ca1-33b5-4100-82d4-13e458f57a3f' (Configured Instance of System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) for PluginType System.Data.IDbConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

StructureMap.StructureMapException: StructureMap Exception Code: 205 Missing requested Instance property "connectionString" for InstanceKey "a54d3ca1-33b5-4100-82d4-13e458f57a3f" at StructureMap.Pipeline.ConstructorInstance.<.ctor>b_0(String key) at StructureMap.Util.Cache2.get_Item(KEY key) at StructureMap.Pipeline.ConstructorInstance.Get(String propertyName, Type pluginType, BuildSession session) at StructureMap.Pipeline.ConstructorInstance.Get[T](String propertyName, BuildSession session) at StructureMap.Pipeline.Arguments.Get[T](String propertyName) at lambda_method(ExecutionScope , IArguments ) at StructureMap.Construction.BuilderCompiler.FuncCompiler1.<>c_DisplayClass2.b__0(IArguments args)

... (Hopefully nothing relevant deleted for space)...

StructureMap Failures: 1 Build/Configuration Failures and 0 Validation Errors

at StructureMap.Container.AssertConfigurationIsValid() at StructureMap.ObjectFactory.AssertConfigurationIsValid() at ConsoleIoCTest.Bootstrapper.BootstrapStructureMap() in U:\dave\VS2008Projects\FMSWeb\FMSWeb\ConsoleIoCTest\Bootstrapper.cs:line 29

Got all that? Neither do I. Why is it saying it's missing the constructor key "connectionString" when I'm passing it as a .ctor argument?

Thanks, and sorry for taking up all that space.

A: 

I think your problem is that you're missing the "Is part" of the Ctor dependency instruction.

For<IDbConnection>()
  .Singleton()
  .Use<SqlConnection>()
  .Ctor<string>().Is(theConnectionString);
PHeiberg