Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.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
Windsor和webforms asp.net的数据访问对象_Asp.net_Nhibernate_Webforms_Castle Windsor_Sessionfactory - Fatal编程技术网

Windsor和webforms asp.net的数据访问对象

Windsor和webforms asp.net的数据访问对象,asp.net,nhibernate,webforms,castle-windsor,sessionfactory,Asp.net,Nhibernate,Webforms,Castle Windsor,Sessionfactory,我创建了一个示例项目,尝试一些新模式,即Dao和IoC 我的Dao定义如下: public class Dao<T> : IDao<T> { protected NHibernate.ISessionFactory _sessionFactory; public Dao(NHibernate.ISessionFactory sessionFactory) { this._sessionFactory = sessionFactor

我创建了一个示例项目,尝试一些新模式,即Dao和IoC

我的Dao定义如下:

public class Dao<T> : IDao<T>
{
    protected NHibernate.ISessionFactory _sessionFactory;

    public Dao(NHibernate.ISessionFactory sessionFactory)
    {
        this._sessionFactory = sessionFactory;
    }

    protected NHibernate.ISession Session
    {
        get { return _sessionFactory.GetCurrentSession(); }
    }

    public T GetById(object id)
    {
        return Session.Get<T>(id);
    }

    ...
}
公共类Dao:IDao
{
受保护的NHibernate.ISessionFactory\u sessionFactory;
公共Dao(NHibernate.ISessionFactory sessionFactory)
{
此._sessionFactory=sessionFactory;
}
受保护的NHibernate.ISession会话
{
获取{return\u sessionFactory.GetCurrentSession();}
}
公共T GetById(对象id)
{
返回会话.Get(id);
}
...
}
我有一个相应的安装程序:

public class DaoInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For(typeof(Data.IDao<>))
            .ImplementedBy(typeof(Data.Dao<>))
            .ServiceOverrides(ServiceOverride.ForKey("SessionFactory").Eq("FirstSessionFactory"))
            .Named("FirstDao"));
    }
}
公共类安装程序:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
容器寄存器(组件)(类型(数据IDao))
.ImplementedBy(typeof(Data.Dao))
.ServiceOverrides(ServiceOverride.ForKey(“SessionFactory”).Eq(“FirstSessionFactory”))
。名为(“第一道”);
}
}

使用MVC模式,我可以定义一个具有构造函数的控制器,该构造函数将接受
IDao myClass
作为参数,Windsor将为我实现所有用正确的SessionFactory实例化Dao的神奇功能。我的问题是,如何在非MVC环境中实现相同的行为?因此,在任何特定的页面上,如何获取myClass的实例?

在MVC之前,ASP.Net不是为使用IoC模式而构建的。MVC具有IoC意识,Windsor和其他IoC实现可以在一些扩展点插入MVC框架,以接管从MVC默认工厂实例化完全配置的控制器的任务。在web表单站点中没有这样的工具可以为您实例化页面类

在web表单项目中使用NHibernate涉及到使用HttpRequest的Items集合,通常还有一个HttpModule,它将在Page类处理请求前后执行代码。在请求开始时,模块创建一个NHibernate会话,并将其放入请求的Items集合(您可以将其放入ASP.Net的唯一位置)。然后页面上的代码可以在会话中获取。页面类将根据需要实例化IDao实现,并将会话传递给它。在请求结束时,模块中的代码将刷新并关闭会话。这样,所有会话管理对页面处理程序中的代码都是透明的。(这就是我在切换到MVC和Sharp架构框架之前所做的。有很多基础架构代码很难获得正确的结果;我很高兴现在改用Sharp架构。这是经过深思熟虑的,而且比我更关注它。)


您仍然可以在web窗体项目中使用IoC容器,但它不是完全透明的。您可以显式地向容器请求IDao的实现。您必须配置IoC容器以向IDao实现提供ISession实现,并将其配置为使用每个web请求语义管理会话生存期。但它并不像MVC中那样干净,因为MVC中的控制器中没有这方面的代码。

谢谢您的回答。不幸的是,因为我对这个领域太陌生(手头的时间非常有限),我现在比以前更加困惑。据我所知,webforms并不适用于国际奥委会,尽管存在一些变通方法,但它们相当复杂。 我想我会放弃Windsor,直到我将项目迁移到MVC,因为现在我使用了一个简单的静态
SessionManager

然后,SessionManager负责在App_Init期间实例化
SessionFactoriesContainer
,定义为:

public static readonly Dictionary<string, ISessionFactory> SessionFactoriesContainer = new Dictionary<string, ISessionFactory>();
public static Dictionary<string, ISession> SessionsContainer
    {
        get
        {
            Dictionary<string, ISession> sessionContainer = (Dictionary<string, ISession>)HttpContext.Current.Items[SESSION_CONTAINER_KEY] ?? new Dictionary<string, ISession>();
            foreach (FactoryType type in Enum.GetValues(typeof(FactoryType)))
            {
                if (!sessionContainer.ContainsKey(type.ToString()))
                    sessionContainer.Add(type.ToString(), null);
            }
            HttpContext.Current.Items[SESSION_CONTAINER_KEY] = sessionContainer;
            return sessionContainer;
        }
    }
public static ISession GetSessionFor(FactoryType type)
    {
        ISession session = SessionsContainer[type.ToString()] ?? SessionFactoriesContainer[type.ToString()].OpenSession();
        session.BeginTransaction();
        SessionsContainer[type.ToString()] = session;

        return session;
    }
虽然
sessioncontainer
是静态的,但由于它存储在HttpContext中,我的理解是每个用户都有自己的容器,我这样假设是错误的吗

SessionManager还有一个类
GetSessionFor
,定义为:

public static readonly Dictionary<string, ISessionFactory> SessionFactoriesContainer = new Dictionary<string, ISessionFactory>();
public static Dictionary<string, ISession> SessionsContainer
    {
        get
        {
            Dictionary<string, ISession> sessionContainer = (Dictionary<string, ISession>)HttpContext.Current.Items[SESSION_CONTAINER_KEY] ?? new Dictionary<string, ISession>();
            foreach (FactoryType type in Enum.GetValues(typeof(FactoryType)))
            {
                if (!sessionContainer.ContainsKey(type.ToString()))
                    sessionContainer.Add(type.ToString(), null);
            }
            HttpContext.Current.Items[SESSION_CONTAINER_KEY] = sessionContainer;
            return sessionContainer;
        }
    }
public static ISession GetSessionFor(FactoryType type)
    {
        ISession session = SessionsContainer[type.ToString()] ?? SessionFactoriesContainer[type.ToString()].OpenSession();
        session.BeginTransaction();
        SessionsContainer[type.ToString()] = session;

        return session;
    }
每当需要新的存储库时,就会调用此方法,然后将ISession传递给构造函数。在请求结束时,每个打开的会话都将被提交,或者在出现错误时回滚事务


我意识到这是一个非常粗糙的实现,但我认为它应该可以工作。如果我在项目结束时有时间,我的目标是重新讨论会话管理,并希望实现安装程序。同时,如果有人有任何其他想法,请随意添加。

您能提供一些如何“模拟”DI的代码示例吗?目前,我只能考虑在需要的页面中从HttpContext检索所需会话,但在这种情况下,Windsor只是一个插销,并不是严格必要的。Krzysztof回答中的链接看起来很有趣。从温莎网站上的搜索中,我看到它有一个用于在web应用程序中使用NHibernate的HttpModule:。您可能会发现它很有用。