我有一个基于ASP.NET MVC 5的应用程序。我正在尝试使用Unity.Mvc容器来帮助我进行依赖项注入。

我有以下DbContext

public class MainContext : DbContext
{
    public DbSet<User> Users { get; set; }
    // .....

    public MainContext(string connectionName)
        : base(connectionName)
    {
        Database.SetInitializer<MainContext>(null);
    }
}


构造MainContext类时要使用的生产值为DefaultConnection。我想将MainContext类注册到容器中,并告诉Unity在使用解析时将DefaultConnection字符串提供给构造函数。

我尝试了以下

container.RegisterType<MainContext>("DefaultConnection", new PerRequestLifetimeManager(), new InjectionConstructor(new ResolvedParameter<string>("DefaultConnection")));


还尝试了这个

container.RegisterType<MainContext>("DefaultConnection", new PerRequestLifetimeManager(), new InjectionConstructor("DefaultConnection"));


但我不断收到以下错误

Resolution of the dependency failed, type = 'System.Web.Mvc.IController', name = 'MyProject.Controllers.HomeController'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value.
-----------------------------------------------
At the time of the exception, the container was:
Resolving MyProject.Controllers.HomeController, MyProject.Controllers.HomeController (mapped from System.Web.Mvc.IController, MyProject.Controllers.HomeController)
Resolving parameter 'unitOfWork' of constructor MyProject.Controllers.HomeController(MyProject.Repositories.Contracts.IUnitOfWork unitOfWork)
Resolving MyProject.Repositories.UnitOfWork,(none) (mapped from MyProject.Repositories.Contracts.UnitsOfWork.IUnitOfWork, (none))
Resolving parameter 'context' of constructor MyProject.Repositories.UnitOfWork(MyProject.Contexts.MainContext context)
Resolving MyProject.Contexts.MainContext,(none)
Resolving parameter 'connectionName' of constructor MyProject.Contexts.MainContext(System.String connectionName)
Resolving System.String,(none)


解决方法是将我的MainContext类更改为此

public class MainContext : DbContext
{
    public DbSet<User> Users { get; set; }
    // .....

    public MainContext(string connectionName)
        : base(connectionName)
    {
        Database.SetInitializer<MainContext>(null);
    }

    public MainContext(string connectionName)
        : this("DefaultConnection")
    {

    }
}


然后像这样注册我的班级

container.RegisterType<MainContext>(new PerRequestLifetimeManager(), new InjectionConstructor());


但是,我不想将实现与特定的连接名称结合在一起。我希望IoC将连接名称提供给MainContext。换句话说,我希望能够在不更改MainContext类的情况下换出连接名称。

我如何正确地告诉Unity-Container注册MainContext类并在构造它时使用DefaultConnection

最佳答案

这并不能直接回答我的问题,但是给了我一个灵活的解决方法。

我创建了以下界面

public interface IDatabaseConnection
{
    string NameOrConnectionString { get; }
}


然后,我创建了该类的以下实现

public class DefaultDatabaseConnection: IDatabaseConnection
{
    public string Name { get; private set; }

    public DefaultDatabaseConnection()
    {
         NameOrConnectionString = "DefaultConnection";
    }

    public DefaultDatabaseConnection(string connectionName)
    {
        NameOrConnectionString = connectionName;
    }
}


然后我将我的MainContext类更改为此

public class MainContext : DbContext
{
    public DbSet<User> Users { get; set; }
    // .....

    public MainContext(IDatabaseConnection connection)
        : base(connection.NameOrConnectionString)
    {
        Database.SetInitializer<MainContext>(null);
    }
}


最后,我像这样注册课程

container.RegisterType<IDatabaseConnection, DefaultDatabaseConnection>("DefaultDatabaseConnection", new InjectionConstructor());
container.RegisterType<MainCompanyContext>(new PerRequestLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDatabaseConnection>("DefaultDatabaseConnection")));


如果提出了更好的答案,我将接受我的其他答案,因此,如果有更简单的方法或是否可以为InjectionConstructor类提供原始字符串,请指导我。

08-25 23:43