首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何配置Unity-Container,通过提供一个字符串值来注册一个类?

我如何配置Unity-Container,通过提供一个字符串值来注册一个类?
EN

Stack Overflow用户
提问于 2018-04-06 02:32:03
回答 2查看 2.2K关注 0票数 2

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

我有以下DbContext

代码语言:javascript
复制
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字符串。

我尝试了以下几种方法

代码语言:javascript
复制
container.RegisterType<MainContext>("DefaultConnection", new PerRequestLifetimeManager(), new InjectionConstructor(new ResolvedParameter<string>("DefaultConnection")));

我也试过这个

代码语言:javascript
复制
container.RegisterType<MainContext>("DefaultConnection", new PerRequestLifetimeManager(), new InjectionConstructor("DefaultConnection"));

但我一直收到以下错误

代码语言:javascript
复制
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类更改为

代码语言:javascript
复制
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")
    {

    }
}

然后像这样注册我的类

代码语言:javascript
复制
container.RegisterType<MainContext>(new PerRequestLifetimeManager(), new InjectionConstructor());

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

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

EN

回答 2

Stack Overflow用户

发布于 2018-04-06 04:32:11

这并没有直接回答我的问题,但给了我一个灵活的变通方法。

我创建了以下接口

代码语言:javascript
复制
public interface IDatabaseConnection
{
    string NameOrConnectionString { get; }
}

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

代码语言:javascript
复制
public class DefaultDatabaseConnection: IDatabaseConnection
{
    public string Name { get; private set; }

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

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

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

代码语言:javascript
复制
public class MainContext : DbContext
{
    public DbSet<User> Users { get; set; }
    // .....

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

最后,我像这样注册了我的类

代码语言:javascript
复制
container.RegisterType<IDatabaseConnection, DefaultDatabaseConnection>("DefaultDatabaseConnection", new InjectionConstructor());
container.RegisterType<MainCompanyContext>(new PerRequestLifetimeManager(), new InjectionConstructor(new ResolvedParameter<IDatabaseConnection>("DefaultDatabaseConnection")));

如果有更好的答案,我会接受其他答案,所以如果有更简单的方法,或者有办法向InjectionConstructor类提供原始字符串,请指导我。

票数 1
EN

Stack Overflow用户

发布于 2018-05-08 03:19:55

静态值

如果你想硬编码一个要传递给构造函数的字符串,你可以简单地这样做:

代码语言:javascript
复制
container.RegisterType<IMyInterface, MyClass>(
    new InjectionConstructor(
        "ThisIsAHardCopedString",
        new ResolvedParameter<IOtherInput>()));

参数化值

但是,如果您想要使用配置文件中的string,例如,您可以这样做:

代码语言:javascript
复制
container.RegisterType<IMyInterface, MyClass>(
    new InjectionConstructor(
        new ResolvedParameter<string>("TheNameOfMyString"),
        new ResolvedParameter<IOtherInput>()));

在主项目中,注册字符串:

代码语言:javascript
复制
container.RegisterInstance<string>("TheNameOfMyString", Settings.Default.ParameterName);

看起来您需要解决方案1,但我建议使用解决方案2,以便将来更容易更改。

注意:您可以将LifetimeManagers与解决方案共存,但它与解决方案无关。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49679172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档