结构映射-为新接口注册旧接口的包装器



早上,

在我维护的代码库中有一个旧接口。让我们称之为IFoo。它几乎已经过时了,几周前进行了一次更改,用接口INewFoo取代了它,但出于向后兼容性的目的,我编写了一个包装器类,它实现了INewFoo,并在构造函数中使用了IFoo。

为了澄清,请考虑以下代码。

    Public Interface IFoo
      Sub DoStuff()
    End Interface
    Public Interface INewFoo
      Sub DoPrettyMuchTheSameStuff()
    End Interface
    Public Class FooToNewFooWrapper
      Implements INewFoo
      Private _foo As IFoo
      Public Sub New(foo As IFoo)
        _foo = foo
      End Sub
      Public Sub DoPrettyMuchTheSameStuff() Implements INewFoo.DoPrettyMuchTheSameStuff
        _foo.DoStuff()
      End Sub
    End Class

对于这两个接口,通过使用StructureMap扫描几个程序集来加载实现。

现在,让我们来谈谈不好的事情。由于我既不能理解也不能更改的原因,旧接口的大多数实现都被放入了表单中。因为这些往往会被显示和处理,所以每次使用ObjectFactory时我都必须创建一个新实例。GetAllInstances(IFoo的(。这仍然没有问题,但我想为每个注册的IFoo实现注册一个INewFoo包装器,这样我就可以使用ObjectFactory了。GetAllInstances(INewFoo(并获取IFoo和INewFoo的所有实现。

我不能迭代IFoo的实现并为每个实现注册一个包装器,因为据我所见,你可以用实例注册它们。

下面的错误代码:

  ObjectFactory.Configure(Sub(config)
                            config.Scan(Sub(scan)
                                          For Each ass In assemblies
                                            scan.Assembly(ass)
                                          Next
                                          scan.AddAllTypesOf(Of IFoo)()
                                        End Sub)
                          End Sub)
Dim oldImplementations = ObjectFactory.GetAllInstances(Of IFoo)()
  ObjectFactory.Configure(Sub(config)
                            For Each implementation In oldImplementations
                              Dim notIterated = implementation
                              config.For(Of INewFoo).Add(Function(x) New FooToNewFooWrapper(notIterated))
                            Next
                          End Sub)

我的问题是:是否可以为IFoo的每个实现注册一个包装器,它总是在创建包装器的新实例之前创建该实现的新实例?

C#和Vb.net中的答案同样受欢迎。

您是否尝试过实现自定义注册约定来满足您的特定需求?自定义注册约定允许非常灵活的扫描和注册

[CLSCompliant(false)]
public class MyRegistration : IRegistrationConvention
/// <inheritdoc />
    public void Process(Type type, Registry registry)
    {           
        Type interfaceType = type.GetInterface(typeof(IFoo).Name);
        if (interfaceType == null)
        {
            return;
        }
        registry.AddType(interfaceType, type, type.Name);
        // Do your stuff with INewFoo
    }
}

配置结构图以使用扫描仪:

ObjectFactory.Configure(item =>
            {
                item.Scan(
                    x =>
                    {
                        x.AssembliesFromPath("c:wheremyassemblyis.dll");
                        x.With(new MyRegistration());
                    });
            });