【问题标题】:Getting Autofac to inject the resolved type of an interface让 Autofac 注入接口的解析类型
【发布时间】:2014-09-30 10:52:06
【问题描述】:

我在实体框架 (EF) 中使用领域驱动设计技术,并且我的一些类没有公共的无参数构造函数。我有一个适用于许多类的服务,其中一些是实体框架,一些是具有公共无参数 ctor 的 DTO。

因此,我希望 Autofac 将接口的已解析类型注入服务 ctor,我自己处理创建/处理已解析 TInterface 类的问题,例如

class MyServiceClass<TInterface> : IMyServiceClass<TInterface>
{
    private Type _classType;

    public MyServiceClass(Type resolvedTypeOfTInterface)
    {
        _classType = resolvedTypeOfTInterface;
    }
}

当 Autofac 解析 IMyServiceClass&lt;TInterface&gt; 时,它会创建一个 MyServiceClass&lt;TInterface&gt; 类型的类,这很好。但是,我也想找出接口 TInterface 解析为的类的 type

我可以看到如何通过this stackoverflow answer 直接访问 Autofac 来获取类,但这意味着直接使用 Autofac 容器,这听起来不是一个好主意。

谁能建议一种通过在容器构建时设置的方法/工厂来注入已解析类型的 TInterface 的方法?

【问题讨论】:

  • 您必须在您的组合根目录中配置 autofac 容器。在这种情况下,autofac 将处理创建类。您不能让 autofac 创建类,而您自己处理创建类。
  • 嗨@Kenneth。我觉得我的解释不够清楚,所以我更新了它。基本上我想要 TInterface 类型的类型,而不是实例。我不能让 Autofac 创建它,因为有时它的构造函数是私有的。我的服务代码可以检查这一点,如果它具有公共无参数构造函数,则使用 Activator.CreateInstance(type) 创建它,或者调用额外代码来处理给定 DDD 类的专用工厂。
  • 你可以在构造函数中请求typeof(TInterface),不需要注入它
  • 嗨@Kenneth。我需要得到 resolved 类型,例如如果我提供了 IMyClass 接口,它应该解析为具有此接口的类,在本例中可能是 MyClass。这就是为什么我需要一个依赖注入框架!我确信这可以做到,但我无法从 Autofac 文档中弄清楚。
  • 如果你执行 typeof,它会得到当前实例的确切类型。如果您提供接口,则该类可以与实现该接口的任何类一起使用,因此您无法在其中注入任何内容,因为其他实现相同接口的类仍然可以使用它。

标签: entity-framework generics domain-driven-design autofac


【解决方案1】:

在找到可行的答案之前,我尝试了多种方法。问题是泛型类似乎不允许某些方法,例如使用 Autofac 的ResolvedParameter。我的回答可能不是最简单的方法,但它确实有效。我的解决方案如下。

首先我更改了 MyServiceClass 以添加一个可以设置类型的方法:

class MyServiceClass <TInterface> : IMyServiceClass <TInterface>, ISetType
{
    private Type _classType;

    //normal ctor with any parameters it needs, but NOT including TInterface
    public MyServiceClass(...) {}

    public void SetType(Type resolvedType)
    {
        _classType = resolvedType;
    }
}

然后我添加了以下代码来向 Autofac 注册 MyServiceClass&lt;&gt; 类型:

builder.RegisterGeneric(typeof (MyServiceClass<>))
    .As(typeof (IMyServiceClass<>))
    .OnActivating(e =>
    {
        var typeToLookup = e.Instance.GetType().GetGenericArguments()[0];
        var foundEntry =
            e.Context.ComponentRegistry.RegistrationsFor(
               new TypedService(typeToLookup )).SingleOrDefault();
        ((ISetType)e.Instance).SetType(foundEntry.Activator.LimitType);
    });

这实现了我所需要的,即如果我有一个参数类型为 MyServiceClass&lt;IMyClass&gt; 的构造函数,那么在 Autofac 创建 MyServiceClass&lt;IMyClass&gt; 之后,私有字段 _classType 将包含 resolved IMyClass 所附加的类,这是我想要的。

任何关于如何以更好的方式做到这一点的 cmets 将不胜感激。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    相关资源
    最近更新 更多