好吧,好像我陷入了我的应用程序结构中。这就是我想要做的事情:
我想在我的存储库中为每个HttpContext创建一个obejctcontext,以防止性能/线程[un]安全问题。理想情况下它会是这样的:
public MyDBEntities ctx
{
get
{
string ocKey = "ctx_" + HttpContext.Current.GetHashCode().ToString("x");
if (!HttpContext.Current.Items.Contains(ocKey))
HttpContext.Current.Items.Add(ocKey, new MyDBEntities ());
return HttpContext.Current.Items[ocKey] as MyDBEntities ;
}
}
问题是我不想在我的DAL中访问HttpContext(存储库所在的位置)。但我必须以某种方式将HttpContext传递给DAL。根据我的问题here的答案,我必须使用IoC模式。理想情况下,我希望在多层架构中实现类似this的功能。
我已经检查过Autofac,看起来很有希望。 但是我不确定如何在多层体系结构中实现这一点(传递Httpcontext以确保每个HttpContext实例化一个ObjectContext)。谁能给我一些关于如何实现这个目标的实例?如何在不直接访问DAL中的HttpContext的情况下了解DAL中的HttpContext?我觉得我在设计多层解决方案时有点迷失。
答案 0 :(得分:3)
我从来没有在WebForms中使用过IoC容器,所以将其作为一些高级解决方案,这可能会进一步改进。
您可以尝试创建一些IoC提供程序作为单例:
public class IoCProvider
{
private static IoCProvider _instance = new IoCProvider();
private IWindsorContainer _container;
public IWindsorContainer
{
get
{
return _container;
}
}
public static IoCProvider GetInstance()
{
return _instance;
}
private IoCProvider()
{
_container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
}
}
您的web.config
必须包含类似的部分(配置基于您的previous post):
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<castle>
<components>
<component id="DalLayer"
service="MyDal.IDalLayer, MyDal"
type="MyDal.MyDalLayer, MyDal"
lifestyle="PerWebRequest">
<!--
Here we define that lifestyle of DalLayer is PerWebRequest so each
time the container resolves IDalLayer interface in the same Web request
processing, it returns same instance of DalLayer class
-->
<parameters>
<connectionString>...</connectionString>
</parameters>
</component>
<component id="BusinessLayer"
service="MyBll.IBusinessLayer, MyBll"
type="MyBll.BusinessLayer, MyBll" />
<!--
Just example where BusinessLayer receives IDalLayer as
constructor's parameter.
-->
</components>
</castle>
<system.Web>
...
</system.Web>
</configuration>
这些接口和类的实现可能如下所示:
public IDalLayer
{
IRepository<T> GetRepository<T>(); // Simplified solution with generic repository
Commint(); // Unit of work
}
// DalLayer holds Object context. Bacause of PerWebRequest lifestyle you can
// resolve this class several time during request processing and you will still
// get same instance = single ObjectContext.
public class DalLayer : IDalLayer, IDisposable
{
private ObjectContext _context; // use context when creating repositories
public DalLayer(string connectionString) { ... }
...
}
public interface IBusinessLayer
{
// Each service implementation will receive necessary
// repositories from constructor.
// BusinessLayer will pass them when creating service
// instance
// Some business service exposing methods for UI layer
ISomeService SomeService { get; }
}
public class BusinessLayer : IBusinessLayer
{
private IDalLayer _dalLayer;
public BusinessLayer(IDalLayer dalLayer) { ... }
...
}
您可以为您的页面定义基类并公开业务层(您可以对可以解析的任何其他类执行相同操作):
public abstract class MyBaseForm : Page
{
private IBusinessLayer _businessLayer = null;
protected IBusinessLayer BusinessLayer
{
get
{
if (_businessLayer == null)
{
_businessLayer = IoCProvider.GetInstance().Container.Resolve<IBusinessLayer>();
}
return _businessLayer;
}
...
}
复杂的解决方案涉及使用自定义PageHandlerFactory
直接解析页面并注入依赖项。如果您想使用此类解决方案,请检查Spring.NET框架(使用IoC容器的另一个API)。