Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 随机抛出异常:TypeInitializationException(涉及Unity容器)?_C#_Asp.net Mvc_Dependency Injection_Unity Container_Appdomain - Fatal编程技术网

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

C# 随机抛出异常:TypeInitializationException(涉及Unity容器)?,c#,asp.net-mvc,dependency-injection,unity-container,appdomain,C#,Asp.net Mvc,Dependency Injection,Unity Container,Appdomain,这对我来说是一个非常奇怪的问题。关键是我不能在本地环境中重现异常(我有完整的源代码来运行调试,连接仍然是来自远程位置的活动连接) 我有一个名为IDataAccess的接口,用于访问我所有控制器中使用的所有sql数据。所以我打算在这里使用单例。 问题是我还使用Unity容器将该实例(作为依赖项)注入到我的控制器中。下面是一个使用该接口的控制器: public AccountController(IDataAccess da){ DataAccess = da; } //this instan

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

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

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 ...
    }
}
public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        UnityContainerConfig.LoadDependencies(container);            
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}
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;
     }
}
应用程序\u Start
的正确位置调用
注册表组件()

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

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

2017年6月5日上午8:40:55-异常:System.TypeInitializationException:“”的类型初始值设定项引发异常。-->System.AppDomainUnloadexException:尝试访问卸载的AppDomain。 at.cctor() ---内部异常堆栈跟踪的结束--- 在DynamicModule.ns.Wrapped_IDataAccess_bf33a9ed4f92418083f514de204b5b2a.CheckLogin(字符串用户名、字符串密码) 在AsmChecklistSite.ApplicationSignInManager.d_u1.MoveNext()中 ---来自引发异常的上一个位置的堆栈结束跟踪--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()中 在AsmChecklistSite.Controllers.AccountController.d_u15.MoveNext()中 ---来自引发异常的上一个位置的堆栈结束跟踪--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中 位于System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) 在System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass37.b__36(IAsyncResult asyncResult) 在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d()中 在System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.c__DisplayClass46.b__3f()中 在System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass33.b_u 32(IAsyncResult asyncResult) 在System.Web.Mvc.Async.AsyncControllerActionInvoker.c_uuDisplayClass21.c_uuDisplayClass2B.b_u1C()中 在System.Web.Mvc.Async.AsyncControllerActionInvoker.c__DisplayClass21.b__1e(IAsyncResult asyncResult)

这发生在登录时,
CheckLogin
的调用,在
AccountController
Login
操作方法中调用

CheckLogin
就这么简单:

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 ...
    }
}
public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        UnityContainerConfig.LoadDependencies(container);            
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}
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;
     }
}
公共异步任务检查登录(字符串用户名、字符串密码)
{            
password=SomeUtil.Encode(密码);
使用(var con=newsqlconnection(LoginConnectionString))
{                
var i=con.ExecuteScalar(“从username=@u和password=@p的用户中选择count(1),新的{u=username,p=password});
返回i>0;
}
}
这里我使用
Dapper
(作为DAL,它扩展了IDbConnection,因此我可以在连接实例上使用扩展方法
ExecuteScalar

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


我已经想不出这是怎么发生的了。Unity容器应该是singleton(它由
UnityContainerConfig
类中的一个静态实例持有,并且由由singleton
DependencyResolver.Current
管理的
UnityDependencyResolver
包装)。
IDataAccess
也使用
ContainerControlled LifetimeManager
注册。所以我希望它的实例是一个单例和持久的?但我仍然不确定异常消息的实际含义(因此它实际上可能不涉及IDataAccess?

为什么您认为拦截部分“不应该在这里涉及”?如果查看堆栈跟踪,可以清楚地看出这实际上与拦截有关,因为异常源于为
IDataAccess
动态生成的代理类,即
Wrapped\u IDataAccess\u bf33a9ed4f92418083f514de204b5b2a
。这是Unity所做的事情。这可能是Unity中的并发错误。糟糕的是,它不再被维护了。@Steven感谢您的回复。我这么想只是因为我在stacktrace里看不清楚。在我看来,
IDataAccess
就是卸载的Appdomain中存在的内容。所以你暗示我应该尝试删除截取,看看它是否有效?事实上,我仍然保留这些截取,网站现在也不像以前那样容易出错。我的意思是,即使是发布的网站,我也几乎无法复制这个例外情况(事实上还没有任何复制)。@Steven我对代码所做的更改只是更改日志路径(即
loggininte)