使Autofac注入解析类型的界面 [英] Getting Autofac to inject the resolved type of an interface

查看:441
本文介绍了使Autofac注入解析类型的界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用实体框架(EF)的域驱动设计技术,我的一些类没有公共的无参数构造函数。我有一个服务可以在一些类上工作,其中一些是实体框架,有些是具有公共无参数的转换器的DTO。



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



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

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

当Autofac解析 IMyServiceClass < TInterface> 它创建一个类型为 MyServiceClass< TInterface> ,这很好。但是我也想找出接口TInterface解析到的类的类型



我可以通过这个stackoverflow答案,但这意味着直接使用Autofac容器,这听起来不是一个好主意。



任何人都可以通过在容器构建时设置的一些方法/工厂来建议一种注入解析类型的TInterface的方法?

解决方案

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



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

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

//正常ctor与任何需要的参数,但不包括TInterface
public MyServiceClass(...){}

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

然后我添加了以下代码注册 MyServiceClass 使用Autofac类型:

  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);
});

这实现了我需要的,即如果我有一个参数类型为<$ c的构造函数$ c> MyServiceClass< IMyClass> 然后在$ code> MyServiceClass< IMyClass> 由Autofac创建私有字段 _classType 将包含IMyClass附加到的已解析的类,这是我想要的。



任何关于如何做的注释这个更好的方式将得到感激之情。


I am using Domain-Driven Design techniques with Entity Framework (EF) and some of my classes do not have public parameterless constructors. I have a service that works on a number of classes, some of which are Entity Framework and some are DTOs with public parameterless ctors.

I would therefore like Autofac to inject the resolved type of the interface into the service ctor and I handle the issues of creating/handling the resolved TInterface class myself, e.g.

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

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

When Autofac resolves IMyServiceClass<TInterface> it create a class of type MyServiceClass<TInterface>, which is fine. However also I want to find out the type of the class that the interface TInterface resolves to.

I can see how I could obtain the class by direct access to the Autofac via this stackoverflow answer but that means using Autofac container directly, which does not sound like a very good idea.

Can anyone suggest a way of injecting the resolved type of the TInterface via some method/factory set up at container build time?

解决方案

I tried a number of approaches before I found a workable answer. The problem is that a generic class didn't seem allow some approaches, such as using Autofac's ResolvedParameter. My answer might not be the simplest way to do this, but it works. My solution is given below.

Firstly I changed MyServiceClass to add a method that can set the type:

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;
    }
}

Then I added the following code to register the MyServiceClass<> type with Autofac:

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);
    });

This achieves what I need, i.e. if I have a constructor that has a parameter of type MyServiceClass<IMyClass> then after the MyServiceClass<IMyClass> is created by Autofac the private field _classType will contain the resolved class that IMyClass is attached to, which is what I want.

Any comments on how to do this in a better way would be gratefully received.

这篇关于使Autofac注入解析类型的界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆