我真的被困在这里。
我有一个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前的原始值,而数据库被另一个源更改。
答案 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; }
}
}