Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get an instance in StructureMap Registy constructor?

How can I get an instance of some type (registered in a different Registry) inside StructureMap Registy constructor? I want to use such a code:

    public RepositoriesRegistry()
    {
        IApplicationSettings lApplicationSettings =
            ObjectFactory.GetInstance<IApplicationSettings>();
        Debug.Assert(lApplicationSettings != null);

        const string cSupportedDevicesConnectionString =
            "metadata=res://*/Models.SupportedDevices.Database.SupportedDevicesModel.csdl|res://*/Models.SupportedDevices.Database.SupportedDevicesModel.ssdl|res://*/Models.SupportedDevices.Database.SupportedDevicesModel.msl;provider=System.Data.SqlClient;provider connection string=\"{0}\"";
        string lSupportedDevicesConnectionString =
            string.Format(cSupportedDevicesConnectionString, lDatabaseConnectionString);
        SupportedDevicesEntities lSupportedDevicesEntities =
            new SupportedDevicesEntities(lSupportedDevicesConnectionString);
        ForRequestedType<SupportedDevicesEntities>().TheDefault.IsThis(
            lSupportedDevicesEntities);
        ForRequestedType<ISupportedDevicesRepository>().TheDefault.IsThis(
            new SupportedDevicesRepository(lSupportedDevicesEntities));

    }

IApplicationSettings is an interface to application settings. The concrete type implementing this interface (currently ConfigFileApplicationSettings class) is registered in another registry like this:

    public ApplicationServicesRegistry()
    {
        ForRequestedType<IApplicationSettings>().TheDefault.IsThis(
            new ConfigFileApplicationSettings());
    }

And both registries are registered in the Bootstrapper:

        #region IBootstrapper Members

    public void BootstrapStructureMap()
    {
        ObjectFactory.Initialize(InitalizeStructureMapContainer);
    }

    #endregion

    #region Private properties

    private static bool HasStarted { get; set; }

    #endregion

    #region Private methods

    private void InitalizeStructureMapContainer(IInitializationExpression x)
    {
        x.IgnoreStructureMapConfig = true;
        x.AddRegistry<ViewModelRegistry>();
        x.AddRegistry<ApplicationServicesRegistry>();
        x.AddRegistry<RepositoriesRegistry>();
        x.AddRegistry<DataOperationsRegistry>();
    }

    #endregion

When I try to get an instance of IApplicationRegisty in registry constructor I've got an error (of course). I don't completly understand how to use StructureMap the right way. May be I should do the thing some different way. But anyway can I get an instance of some type early registered in an Registry constructor?

like image 461
Mike Eshva Avatar asked Aug 15 '09 18:08

Mike Eshva


1 Answers

I ran into this same problem today. The answer from Jeremy Miller (no relation :) ) is that StructureMap is not setup to create instances at configuration time.

The workaround he recommended and that I used was to create a container just for the settings. Here is my solution.

public class SettingsRegistry : Registry
{
    public SettingsRegistry()
    {
        ForRequestedType<ISettingsProvider>().TheDefault.Is.OfConcreteType<AppSettingsProvider>();

        Scan(s =>
        {
            s.TheCallingAssembly();
            s.With<SettingsScanner>();
        });
    }
}

public class RegistryNeedingSettings : Registry
{
    public RegistryNeedingSettings()
    {
        var settingsContainer = new Container(new SettingsRegistry());
        var coreSettings = settingsContainer.GetInstance<CoreSettings>();

        //configuration needing access to the settings.
    }
}

I moved everything settings into its own registry and made sure the settings registry gets configured before the dependent registry.

Hope this helps.

like image 90
KevM Avatar answered Nov 08 '22 17:11

KevM