我目前有这样的事情:
new ContainerBuilder()
.RegisterGeneric(typeof(MyFactory<>))
.As(typeof(IMyFactory<>))
.WithParameter("param", "abc")
.SingleInstance();
我想限制上面的T(在MyFactory<T>
中)在特定命名空间中。
RegisterGeneric()
这可能吗?如果我使用RegisterAssemblyTypes()
,那么我应该可以使用Where(type => type.IsInNamespace("..."))
并单独注册每种类型。
这是推荐的方法吗?
答案 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<>
实例化。如果此注册取决于其他注册或初始化需要时间,则可能会出现问题。