miso_soup3 Blog

主に ASP.NET 関連について書いています。

IoCフレームワーク、クラスとConfigファイルの両方から設定する

IoCフレームワークの設定で、スペルミスが面倒なのでクラスで設定したい…
けど、この部分だけはDebug/Release時で変更したい…

という悩みに対して、StructureMap&Unityでアレコレ試してみましたができました!
両方ともできましたが、設定が被った時の、Configファイルとクラスの優先度が違っていました。

StructureMap

クラスの設定です

public static class StructureMapBootstrap
{
	public static void Configure()
	{
		ObjectFactory.Initialize(x =>
		{
			//WebConfigでの設定を有効にします。
			x.PullConfigurationFromAppConfig = true;

			x.For<IPersonService>().Use<PersonService>();			
		});
	}
}

WebConfigでの設定です。
Debug/Release時で変更したいものだけを設定します。
(私は、メール送信にて、送信せずに出力だけして欲しい時に利用しています。)

<StructureMap>
	<Assembly Name="StructureMapConfig" />

	<DefaultInstance
		PluginType="StructureMapConfig.Models.ICategoryService, StructureMapConfig"
		PluggedType="StructureMapConfig.Models.CategoryService, StructureMapConfig" />		
</StructureMap>
設定がかぶると…

同じ型に対して、クラスとWebConfigでそれぞれ違うものを設定すると、
WebConfigの設定が優先されました。

Unity

クラスの設定です

private static IUnityContainer BuildUnityContainer()
{
    IUnityContainer container = new UnityContainer();

    container.RegisterType<IPersonService, PersonService_A>();
    
    //WebConfigでの設定を有効にします。
    container.LoadConfiguration();

    return container;
}

WebConfigでの設定です。

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
	<namespace name="UnityTry.Models" />
	<assembly name="UnityTry" />

	<container>
		<register type="IPersonService" mapTo="PersonService_B" />
	</container>

</unity>
設定がかぶると…

同じ型に対して、クラスとWebConfigでそれぞれ違うものを設定すると、
後で設定されたものが取得されます。

//WebConfigでの設定を有効にします。
container.LoadConfiguration();

container.RegisterType<IPersonService, PersonService_A>();

↑この順番だと、PersonService_Aが取得されますが

container.RegisterType<IPersonService, PersonService_A>();

//WebConfigでの設定を有効にします。
container.LoadConfiguration();

↑こうすると、WebConfigで設定したPersonService_Bが取得されます。