私のAsp.netMVCプロジェクトでは
Unityコンテナを初期化するブートラッパーがあります。
理由はわかりませんが、
System.Core.dllでタイプ「System.StackOverflowException」の未処理の例外が発生しました
私はダブルチェックを行い、登録は初期化子でのみ行われます。
すべての依存関係は、ctorにのみ注入されます。
何が原因でしたか?
_ protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
Initializer.Initialize();
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
_
BundleConfig.RegisterBundles(BundleTable.Bundles);
の後に失敗します
_public static class Initializer
{
private static bool isInitialize;
private static readonly object LockObj = new object();
private static IUnityContainer defaultContainer = new UnityContainer();
static Initializer()
{
Initialize();
}
public static void Initialize()
{
if (isInitialize)
return;
lock (LockObj)
{
IUnityContainer container = defaultContainer;
//registering Unity for MVC
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
//registering Unity for web API
// GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
#region managers
container.RegisterType<ISettingsManager, SettingsManager>();
container.RegisterType<IMamDataManager, MamDataManager>();
container.RegisterType<IAppsDataManager, AppsDataManager>();
#endregion
#region Dals
container.RegisterType<IDal<ClientService.DAL.EntityFramework.App>, AppsDal>();
#endregion Dals
#region cache
container.RegisterType<ICache<string, ClientService.DAL.EntityFramework.Group>, GroupsCache>(new ContainerControlledLifetimeManager());
container.RegisterType<ICache<string, ClientService.DAL.EntityFramework.App>, AppsCache>(new ContainerControlledLifetimeManager());
container.RegisterType<ICache<string, SettingsServiceData>, SettingsServiceDataCache>(new ContainerControlledLifetimeManager());
#endregion cache
#region Pollers
container.RegisterType<IPoller<ClientService.DAL.EntityFramework.Group>, GroupsPoller>(new ContainerControlledLifetimeManager());
container.RegisterType<IPoller<ClientService.DAL.EntityFramework.App>, AppsPoller>(new ContainerControlledLifetimeManager());
container.RegisterType<IPoller<SettingsServiceData>, SettingsPoller>(new ContainerControlledLifetimeManager());
#endregion Pollers
container.RegisterType<IDefaultConfigurationGroupSingleton, DefaultConfigurationGroupSingleton>(new ContainerControlledLifetimeManager());
container.RegisterType<IApplicationLogger, Log4NetLogger>();
if (!isInitialize)
{
isInitialize = true;
}
}
}
}
_
コードを提供しないと、これは循環依存によるものだと思います。もう1つの考えられる理由は、コンストラクターの1つに不適切なループがあることです。
例として、AクラスではBのインスタンスを解決する必要があります。 Bクラスでは、Cクラスのインスタンスを解決する必要があり、Cクラスでは、Aのインスタンスを解決する必要があります。これにより、無限ループが発生します。
public class A
{
public A(B b)
{
}
}
public class B
{
public B(C c)
{
}
}
public class C
{
public C(A a)
{
}
}
Rafaelが述べたように、これは通常循環依存関係によって引き起こされますが、これらの依存関係が必要な場合は、それらのいくつかを手動で解決することで修正できます。
例えば:
// Register the UnityContainer with itself
container.RegisterInstance<IUnityContainer>(container);
public class A
{
public A(B b) {}
}
public class B
{
public B(C c) {}
}
public class C
{
private readonly IUnityContainer _container;
private A _a => _container.Resolve<A>();
public C(IUnityContainer container) {
_container = container;
}
}
これは、Cを使用するときまで、Aについて知る必要なしにCを構築できることを意味します:)