结构图InstanceScope.Hybrid与asp.net mvc行为不端

时间:2009-03-26 19:42:26

标签: asp.net-mvc linq-to-sql structuremap

我真的被困在这里。

我有一个asp.net mvc应用程序并使用StructureMap 2.5.3(SM)在我的控制器中注入服务和存储库类。 所有控制器均由SM工厂制造。

我还有一个Linq to SQL datacontext,我希望通过混合缓存。

public class DBRegistry:Registry
{
    public  DBRegistry()
    {
        ForRequestedType<SharpShopDataContext>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Hybrid)
            .TheDefault.IsThis(new SharpShopDataContext());
    }
}

缓存似乎不起作用,因此我遇到了datacontext的问题。

多个浏览器请求都返回相同的dbcontext ?! 在我的一个存储库类中,我已经放了这个代码。 Debug.WriteLine(“db hashcode:”+ db.GetHashCode()+“”+ DateTime.Now.ToString());

其中db = datacontext 我还使用db和使用存储库的服务打印存储库的哈希码,这里是多个请求的打印:

服务哈希码:6238972 26-3-2009 18:59:34

repository hashcode:21756593 26-3-2009 18:59:34

db hashcode:7043935 26-3-2009 18:59:34

服务哈希码:59389065 26-3-2009 18:59:34

repository hashcode:8331620 26-3-2009 18:59:34

db hashcode:7043935 26-3-2009 18:59:34

服务哈希码:11291358 26-3-2009 18:59:38

repository hashcode:13848497 26-3-2009 18:59:38

db hashcode:7043935 26-3-2009 18:59:38

服务哈希码:42509361 26-3-2009 18:59:38

repository hashcode:56101068 26-3-2009 18:59:38

db hashcode:7043935 26-3-2009 18:59:38

正如您所看到的,7043935是每次请求时datacontext的哈希码,但服务和存储库每次都会获得一个新的实例和哈希码。

由于此原因,我得到了奇怪的错误,例如dataconcurrency异常,因为dbcontext具有4个webrequests前的原始值,而数据库被另一个源更改。

3 个答案:

答案 0 :(得分:3)

如果您尝试让SM为每个HttpRequest创建一个DataContext,那么新的Registry配置应该可以正常工作

ForRequestedType<ISharpShopDataContextWrapper>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Hybrid)
            .TheDefaultIsConcreteType<SharpShopDataContextWrapper>();

InstanceScope.Hybrid是您应该使用的SM(v2.5.3)枚举值,如果您想要“每个线程或ASP.NET请求一次”生命周期(让我们转到源Chad Myers,SM contributor

如果您正确配置应用程序基础结构,则不应“必须更改大量代码”。我很有兴趣知道为什么你决定为SharpShopDataContext创建一个包装类? LinqToSql DataContext被声明为部分类,因此您可以轻松创建实现任何其他接口的SharpShopDataContext部分类:

LinqToSql 生成了部分类定义

public partial class SharpShopDataContext: System.Data.Linq.DataContext{
    /*Linq2Sql gen here*/
}

您的部分类定义

public partial class SharpShopDataContext: ISharpShopDataContext{
   /*your implementation here*/
}

你可以考虑阅读一些Jeremy Miller's StructureMap articles。一旦你很好地理解了它的功能,你就可能重构整个MVC应用程序。我知道我目前的基础MVC应用程序框架是高度可配置/可测试的,因为SM IoC(以及试验/错误/气味/重构的船载荷)。

答案 1 :(得分:2)

这绝对是一个问题:

.TheDefault.IsThis

您正在指定一个特定的实例,即使指定了PerRequest,它也会导致它返回相同的实例。请注意,您已更改为(在您的解决方法中):

.TheDefaultIsConcreteType<SharpShopDataContextWrapper>();

聚苯乙烯。我没有使用过HybridScope,但是我有一个使用默认实例范围(PerRequest)的生产应用程序,每次传递datacontext时它肯定会给出一个新的应用程序。如果要具体控制实例化的方式,请尝试接受表达式的方法之一,即发送方式:

() => new MyDataContext()

答案 2 :(得分:0)

我有一个解决方法,但不要为此感到高兴,因为知道我必须更改大量代码,并且通过反复试验发现它。

我现在用:

            ForRequestedType<ISharpShopDataContextWrapper>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Hybrid)
            .TheDefaultIsConcreteType<SharpShopDataContextWrapper>();

接口的注入/缓存似乎有效。 这是接口+具体包装器的实现。

所以它真的看起来像SM中的错误,或者我错过了什么?

public interface ISharpShopDataContextWrapper
{
    SharpShopDataContext DataContext
    {
        get;
    }
}

public class SharpShopDataContextWrapper : ISharpShopDataContextWrapper
{
    SharpShopDataContext db;

    public SharpShopDataContextWrapper()
    {
        db = new SharpShopDataContext();
    }
    public SharpShopDataContext DataContext
    {
        get { return db; }
    }
}