使用CSLA和Entity Framework进行Visual Studio 2012测试

14

在VS2010中,我的MSTest测试运行得非常好。

在运行VS2012时,我遇到了一个错误。该测试使用自定义的业务主体设置Csla.ApplicationContext.User。当要求EntityFramework提供新的ObjectContext时,我收到一个SerializationException,说明找不到我的自定义业务主体类型。

所有使用EntityFramework的测试在通过VS2012的测试运行程序或Resharper7的测试运行程序时均失败。我尝试了NCrunch的测试运行程序,它们都通过了。

我应该如何解决这个问题?


2
我找到了真正的问题。VS2012在单独的AppDomain中运行测试,我们的数据访问层通过反射加载。仍然不确定为什么EF需要了解主体,但我们的解决方案是在访问EF之前将我们的主体重置为GenericPrincipal,然后再放回原来的主体。我仍在思考也许一个IoC容器可以缓解这个问题。 - Jamie Altizer
如果您的发现解决了问题,您可以将其作为答案添加并标记为已接受吗? - Ryan Gates
2个回答

3

我找到了真正的问题。VS2012在一个单独的AppDomain中运行测试,我们的数据访问层通过反射加载。仍然不确定为什么EF需要了解主体,但我们的解决方案是在访问EF之前将我们的主体重置为GenericPrincipal,然后再放回原来的主体。我仍在思考,也许一个IoC容器可以缓解这个问题。


实际上,我认为 EF 并不想特别了解你的 principal,但它可能会查看它。当它尝试将对象从原始应用程序域编组到此新应用程序域时,它会失败(因为它找不到定义你的 principal 的程序集)。 - Andy

0

你还应该注意到 .net 4.5 声明主体的方法。 我在 VS2012 上使用 EF5.0,目标是 .net4.5 测试 WindowsIdentity.GetCurrent().Name;
Thread.CurrentPrincipal 的区别。

我在 FORMS auth 下使用了一个小例程。 这样 Windows Auth 和 Forms Auth 就可以一起使用。

虽然不是完全相同的情况,但它确实突出了重要的区别,当一切正常时往往会被忽视。
值得快速阅读... http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.current

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;


namespace BosIdentityManager
{
public class BosPrincipal
{
    /// <summary>
    /// The current principal is set during FORMS authentication.  If WINDOWS auth mode is in use, Windows sets it.
    /// </summary>
    /// <returns> The Name from Thread.CurrentPrincipal.Identity.Name unless alternate delegate is configured</returns>  
    public static string GetCurrentUserName()
    {
    //   http://msdn.microsoft.com/en-us/library/system.security.claims.claimsprincipal.current   
    //  with forms auth and windows integrated,ClaimsPrincipal.Current will be set.

        var prin = ClaimsPrincipal.Current;  //normally this reverts to Thread.CurrentPrincipal, but can chnage !
        return prin.Identity.Name;

    }

    public static string GetCurrentWindowsUserName()
    {
        return WindowsIdentity.GetCurrent().Name;   
    }

    public static void SetPrincipal(BosMasterModel.Membership memb)
   {
       var claims = new List<Claim>(){ new Claim(ClaimTypes.Name, memb.SystemUser.UserName),
                                       new Claim(ClaimTypes.NameIdentifier,memb.UserId.ToString()),
                                       new Claim(ClaimTypes.Role, "SystemUser") };

       var ClaimsId = new ClaimsIdentity(claims,"Forms");

       var prin = new ClaimsPrincipal(ClaimsId);
       Thread.CurrentPrincipal = prin;

   }
}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接