使用自定义构造函数进行代码优先迁移

时间:2015-05-27 08:29:22

标签: c# asp.net-mvc structuremap

我正在使用Code First Migrations with Entity Framework。我使用的自定义构造函数具有一个特定于某个用户登录应用程序的连接字符串。

当de application加载时,我希望使用用户连接字符串初始化数据库,如果数据库上下文中有任何更改,则将其迁移到最新版本。我使用Structure map来注入工作单元。

Global Asax

ObjectFactory.Configure(cfg =>
        {
            cfg.AddRegistry(new StandardRegistry());
            cfg.AddRegistry(new ControllerRegistry());
            cfg.AddRegistry(new ActionFilterRegistry(() => Container ?? ObjectFactory.Container));
            cfg.AddRegistry(new MvcRegistry());
            cfg.AddRegistry(new TaskRegistry());
            cfg.AddRegistry(new ModelMetadataRegistry());
        });

StandardRegistry类

 For<ICustomerUnitOfWork>().Use(new CustomerUnitOfWork(new CustomerContext()));
        For<CustomerContext>().Use(new CustomerContext());

此时我不知道用户的连接字符串,因为用户未登录。模型更改时出现问题,因为上下文模型已更改,结构图会抛出异常。

上下文

private static string _connectionString;

    static CustomerContext()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<CustomerContext, Configuration>());
    }

    public CustomerContext()
        : base(string.IsNullOrEmpty(_connectionString) ? "FooDatabase" : _connectionString)
    {
        if (string.IsNullOrEmpty(_connectionString))
            Database.SetInitializer(new CustomerContextInitializer());
    }


    public CustomerContext(string connectionString)
        : base(connectionString)
    {
        if (string.IsNullOrEmpty(_connectionString))
            Database.SetInitializer(new CustomerContextInitializer());
        _connectionString = connectionString;
    }

CustomerContextInitializer

 public class CustomerContextInitializer : CreateDatabaseIfNotExists<CustomerContext>
{
    protected override void Seed(CustomerContext context)
    {
        var informationService = new InformationService
        {
            ObjectState = ObjectState.Added,
            ConnectorClass =
                "Conexio.InformationService.Contracts.IInformationService, Conexio.InformationService.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            DisplayName = "IInformationService"
        };

有没有办法在运行时将规则添加到standardRegistry类以使用connectionstring调用构造函数?或者还有另一种方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

如果我正确理解你的问题,你最好的方法就是创建一个工厂类,它负责在运行时创建ICustomerUnitOfWork实例,然后可以在StructureMap注册表中进行配置,如下所示:

this.For<ICustomerUnitOfWork>().Use(ctx => ctx.GetInstance<YourFactoryClass>().ResolveCustomerUnitOfWork());

然后,您的ICustomerUnitOfWork将解析为您的工厂类,该工厂类可以将一组依赖项注入其中,以确定正确的上下文。

public interface ICustomerUnitOfWork
{

}

public class YourFactoryClass
{
    public YourFactoryClass(string connectionString)
    {

    }

    public ICustomerUnitOfWork ResolveCustomerUnitOfWork()
    {
        // Perform runtime configuration

        return unitOfWork;
    }
}

我希望这有帮助!