注册通用,其中T在特定名称空间中

时间:2015-04-23 16:26:14

标签: c# autofac

我目前有这样的事情:

new ContainerBuilder()
      .RegisterGeneric(typeof(MyFactory<>))
      .As(typeof(IMyFactory<>))
      .WithParameter("param", "abc")
      .SingleInstance();

我想限制上面的T(在MyFactory<T>中)在特定命名空间中。

RegisterGeneric()这可能吗?如果我使用RegisterAssemblyTypes(),那么我应该可以使用Where(type => type.IsInNamespace("..."))并单独注册每种类型。

这是推荐的方法吗?

1 个答案:

答案 0 :(得分:1)

没有简单的方法可以做到这一点。顺便说一句,您可以使用OnActivating事件替换基于类型命名空间的实例。

假设您在不同的命名空间中有类型:

public interface IFoo
{ }
namespace X
{
    public class FooX : IFoo { }
}
namespace Y
{
    public class FooY : IFoo { }
}

1个通用Factory和2个具体:

public interface IFooFactory<TFoo>
    where TFoo : IFoo
{
    TFoo Create();
}

public class XFactory<TFoo> : IFooFactory<TFoo>
    where TFoo : IFoo
{
    public TFoo Create()
    {
        throw new NotImplementedException();
    }
}
public class YFactory<TFoo> : IFooFactory<TFoo>
    where TFoo : IFoo
{
    public TFoo Create()
    {
        throw new NotImplementedException();
    }
}
public class DefaultFactory<TFoo> : IFooFactory<TFoo>
    where TFoo : IFoo
{
    public TFoo Create()
    {
        throw new NotImplementedException();
    }
}

您可以像这样注册您的特定工厂:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(XFactory<>))
       .Named("ProjectNamespace.X", typeof(IFooFactory<>));
builder.RegisterGeneric(typeof(YFactory<>))
       .Named("ProjectNamespace.Y", typeof(IFooFactory<>));

你的通用工厂是这样的:

builder.RegisterGeneric(typeof(DefaultFactory<>))
        .As(typeof(IFooFactory<>))
        .OnActivating(e =>
        {
            Type elementType = e.Instance.GetType().GetGenericArguments()[0];
            Type fooFactoryType = typeof(IFooFactory<>).MakeGenericType(elementType); 
            Service service = new KeyedService(elementType.Namespace, fooFactoryType);
            Object fooFactory = e.Context.ResolveOptionalService(service, e.Parameters);
            if (fooFactory != null)
            {
                e.ReplaceInstance(fooFactory);
            }
        });

仅将默认工厂注册为IFooFactory<>。如果您尝试解析IFooFactory<X.FooX>,那么OnActivating事件将替换默认工厂实例,您将获得XFooFactory<X.FooX>

这样做的主要缺点是每次都会DefaultFactory<>实例化。如果此注册取决于其他注册或初始化需要时间,则可能会出现问题。