注入Startup类

时间:2017-10-05 19:17:51

标签: asp.net-mvc nhibernate

是否可以使用像Castle Windsor这样的IOC框架注入Startup方法。我的意思是这样的:

public class Startup()
{
   IMyObject MyObject = new MyObject();

   public Startup(MyObject myObject)
   {
      MyObject = myObject();
   }
}

我正在尝试使用NHibernate在启动时删除并创建数据库。另外还有一个更好的"放置并使用NHibernate创建数据库?

1 个答案:

答案 0 :(得分:0)

我使用specflow进行集成测试。

我有一个NHibernateInitializer类,我在所有看起来像这样的项目中继承了这个

public abstract class NHibernateInitializer : IDomainMapper
{
    protected Configuration Configure;
    private ISessionFactory _sessionFactory;
    private readonly ModelMapper _mapper = new ModelMapper();
    private Assembly _mappingAssembly;
    private readonly String _mappingAssemblyName;
    private readonly String _connectionString;

    protected NHibernateInitializer(String connectionString, String mappingAssemblyName)
    {
        if (String.IsNullOrWhiteSpace(connectionString))
            throw new ArgumentNullException("connectionString", "connectionString is empty.");

        if (String.IsNullOrWhiteSpace(mappingAssemblyName))
            throw new ArgumentNullException("mappingAssemblyName", "mappingAssemblyName is empty.");

        _mappingAssemblyName = mappingAssemblyName;
        _connectionString = connectionString;
    }

    public ISessionFactory SessionFactory
    {
        get
        {
            return _sessionFactory ?? (_sessionFactory = Configure.BuildSessionFactory());
        }
    }

    private Assembly MappingAssembly
    {
        get
        {
            return _mappingAssembly ?? (_mappingAssembly = Assembly.Load(_mappingAssemblyName));
        }
    }

    public void Initialize()
    {
        Configure = new Configuration();
        Configure.EventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { new EventListener() };
        Configure.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { new EventListener() };
        Configure.SessionFactoryName(System.Configuration.ConfigurationManager.AppSettings["SessionFactoryName"]);
        Configure.DataBaseIntegration(db =>
                                      {
                                          db.Dialect<MsSql2008Dialect>();
                                          db.Driver<SqlClientDriver>();
                                          db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
                                          db.IsolationLevel = IsolationLevel.ReadCommitted;
                                          db.ConnectionString = _connectionString;
                                          db.BatchSize = 20;
                                          db.Timeout = 10;
                                          db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
                                      });
        Configure.SessionFactory().GenerateStatistics();

        Map();
    }

    public virtual void InitializeAudit()
    {
        var enversConf = new Envers.Configuration.Fluent.FluentConfiguration();

        enversConf.Audit(GetDomainEntities());

        Configure.IntegrateWithEnvers(enversConf);
    }

    public void CreateSchema()
    {
        new SchemaExport(Configure).Create(false, true);
    }

    public void DropSchema()
    {
        new SchemaExport(Configure).Drop(false, true);
    }

    private void Map()
    {
        _mapper.AddMappings(MappingAssembly.GetExportedTypes());
        Configure.AddDeserializedMapping(_mapper.CompileMappingForAllExplicitlyAddedEntities(), "MyWholeDomain");
    }

    public HbmMapping HbmMapping
    {
        get { return _mapper.CompileMappingFor(MappingAssembly.GetExportedTypes()); }
    }

    public IList<HbmMapping> HbmMappings
    {
        get { return _mapper.CompileMappingForEach(MappingAssembly.GetExportedTypes()).ToList(); }
    }

    /// <summary>
    /// Gets the domain entities.
    /// </summary>
    /// <returns></returns>
    /// <remarks>by default anything that derives from EntityBase and isn't abstract or generic</remarks>
    protected virtual IEnumerable<System.Type> GetDomainEntities()
    {
        List<System.Type> domainEntities = (from t in MappingAssembly.GetExportedTypes()
                                            where typeof(EntityBase<Guid>).IsAssignableFrom(t)
                                            && (!t.IsGenericType || !t.IsAbstract)
                                            select t
                                           ).ToList();

        return domainEntities;
    }
}

然后在我的global.asax Application_Begin事件处理程序中配置它

    public class MvcApplication : HttpApplication
    {
        private const String Sessionkey = "current.session";
        private static IWindsorContainer Container { get; set; }
        private static ISessionFactory SessionFactory { get; set; }

        public static ISession CurrentSession
        {
            get { return (ISession) HttpContext.Current.Items[Sessionkey]; }
            private set { HttpContext.Current.Items[Sessionkey] = value; }
        }

        protected void Application_Start()
        {
            Version version = Assembly.GetExecutingAssembly().GetName().Version;
            Application["Version"] = String.Format("{0}.{1}", version.Major, version.Minor);
            Application["Name"] = ConfigurationManager.AppSettings["ApplicationName"];

            //create empty container
            //scan this assembly for any installers to register services/components with Windsor
            Container = new WindsorContainer().Install(FromAssembly.This());

            //API controllers use the dependency resolver and need to be initialized differently than the mvc controllers
            GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(Container.Kernel);

            //tell ASP.NET to get its controllers from Castle
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container.Kernel));

            //initialize NHibernate
            ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings[Environment.MachineName];

            if (connectionString == null)
                throw new ConfigurationErrorsException(String.Format("Connection string {0} is empty.",
                    Environment.MachineName));

            if (String.IsNullOrWhiteSpace(connectionString.ConnectionString))
                throw new ConfigurationErrorsException(String.Format("Connection string {0} is empty.",
                    Environment.MachineName));

            string mappingAssemblyName = ConfigurationManager.AppSettings["NHibernate.Mapping.Assembly"];

            if (String.IsNullOrWhiteSpace(mappingAssemblyName))
                throw new ConfigurationErrorsException(
                    "NHibernate.Mapping.Assembly key not set in application config file.");

            var nh = new NHInit(connectionString.ConnectionString, mappingAssemblyName);
            nh.Initialize();
            nh.InitializeAudit();
            SessionFactory = nh.SessionFactory;

            AutoMapConfig.RegisterMaps();
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            ModelBinderConfig.RegisterModelBinders(ModelBinders.Binders);

            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
        }

        protected void Application_OnEnd()
        {
            //dispose Castle container and all the stuff it contains
            Container.Dispose();
        }

        protected void Application_BeginRequest() { CurrentSession = SessionFactory.OpenSession(); }

        protected void Application_EndRequest()
        {
            if (CurrentSession != null)
                CurrentSession.Dispose();
        }
    }
}