随机抛出异常:TypeInitializationException(涉及Unity容器)?

时间:2017-06-05 02:55:01

标签: c# asp.net-mvc dependency-injection unity-container appdomain

这对我来说是一个非常奇怪的问题。关键是我无法在本地环境中重现异常(我有完整的源代码来运行调试,连接仍然是来自远程位置的实时连接)。

我有一个名为IDataAccess的接口,用于访问我所有控制器中使用的所有sql数据。所以我打算在这里使用单身人士。 问题是我还使用Unity Container将该实例(作为依赖项)注入我的控制器。这是一个使用该接口的控制器:

public AccountController(IDataAccess da){
   DataAccess = da;
}
//this instance is used inside the controller
public IDataAccess DataAccess {get;set;}

以下是我配置Unity容器的方法,我有一个单独的类:

public class UnityContainerConfig
{
    public static IUnityContainer Uc { get; private set; }
    public static void LoadDependencies(IUnityContainer uc = null)
    {
        Uc = uc ?? new UnityContainer();
        Uc.AddNewExtension<Interception>();
        //some other not-related registration here 
        Uc.RegisterType<IDataAccess, DataAccess>(new ContainerControlledLifetimeManager(), 
             new Interceptor<InterfaceInterceptor>(), 
             new InterceptionBehavior<UserInfoCacheInterceptionBehavior>(), 
             new InjectionConstructor(WebConfigurationManager.ConnectionStrings["TestConnection"].ConnectionString,
                                      WebConfigurationManager.ConnectionStrings["loginConnection"].ConnectionString),
             new InterceptionBehavior<LoggingInterceptionBehavior>()
          );
       //other registrations ...
    }
}

最后,我调用LoadDependencies中的UnityConfig.LoadComponents(我还使用Unity.Mvc5将Unity与MVC集成),如下所示:

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        UnityContainerConfig.LoadDependencies(container);            
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}

RegisterComponents()的正确位置调用Application_Start

因此,您可以看到我有IDataAccess的实施名为DataAccess。这有一个构造函数接受2个字符串(2个连接字符串)(这些是使用InjectionConstructor注入的)。我还添加了一些截取来拦截IDataAccess的日志记录和缓存(我认为这部分不应该涉及)。

这是随机抛出的异常(我从记录的文本中复制了它):

  

6/5/2017 8:40:55 AM - 异常:System.TypeInitializationException:&#39;&lt; Module&gt;&#39;的类型初始值设定项抛出一个例外。 ---&GT; System.AppDomainUnloadedException:尝试访问已卸载的AppDomain。      at .cctor()      ---内部异常堆栈跟踪结束---      在DynamicModule.ns.Wrapped_IDataAccess_bf33a9ed4f92418083f514de204b5b2a.CheckLogin(String userName,String password)      在AsmChecklistSite.ApplicationSignInManager.d__1.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()      在AsmChecklistSite.Controllers.AccountController.d__15.MoveNext()   ---从抛出异常的先前位置开始的堆栈跟踪结束---      在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)      在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      在System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult)      在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass37.b__36(IAsyncResult asyncResult)      在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d()      在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters。&lt;&gt; c__DisplayClass46.b__3f()      在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass33.b__32(IAsyncResult asyncResult)      在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass21。&lt;&gt; c__DisplayClass2b.b__1c()      在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass21.b__1e(IAsyncResult asyncResult)

在登录时发生这种情况,CheckLogin的调用是在Login的{​​{1}}操作方法内调用的。

AccountController就像这样简单:

CheckLogin

这里我使用public async Task<bool> CheckLogin(string userName, string password) { password = SomeUtil.Encode(password); using(var con = new SqlConnection(LoginConnectionString)) { var i = con.ExecuteScalar<int>("select count(1) from Users where username=@u and password=@p", new { u = userName, p = password }); return i > 0; } } (作为DAL,它扩展了IDbConnection,因此我可以在连接实例上使用扩展方法Dapper。)

正如我之前所说,我无法在我的本地环境中重现这一点。只有在将站点发布到我的服务器之后,才会随机抛出异常。有时我可以登录确定,甚至在此之后尝试多次。但有时它会因异常而失败(一旦失败,在尝试之后尝试多次尝试仍会失败)。然后在一段时间后,我仍然可以再次登录OK。这真的很奇怪。

我已经没有关于如何发生这种情况的想法。 Unity容器应该是单例(它由ExecuteScalar类中的静态实例保存,也由UnityContainerConfig包裹,由单例UnityDependencyResolver管理) 。 DependencyResolver.Current也使用IDataAccess注册。所以我希望它的实例是单例并持久化?我仍然不确定异常消息的实际含义(因此它实际上可能不涉及IDataAccess?)

0 个答案:

没有答案