Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 注册泛型,其中T位于特定命名空间中_C#_Autofac - Fatal编程技术网

C# 注册泛型,其中T位于特定命名空间中

C# 注册泛型,其中T位于特定命名空间中,c#,autofac,C#,Autofac,我现在有这样的东西: new ContainerBuilder() .RegisterGeneric(typeof(MyFactory<>)) .As(typeof(IMyFactory<>)) .WithParameter("param", "abc") .SingleInstance(); newcontainerbuilder() .RegisterGeneric(类型(MyFactory)) .As(类型(IMY工

我现在有这样的东西:

new ContainerBuilder()
      .RegisterGeneric(typeof(MyFactory<>))
      .As(typeof(IMyFactory<>))
      .WithParameter("param", "abc")
      .SingleInstance();
newcontainerbuilder()
.RegisterGeneric(类型(MyFactory))
.As(类型(IMY工厂))
.WithParameter(“参数”、“abc”)
.SingleInstance();
我想限制上面提到的T(在
MyFactory
中)在特定名称空间中的位置

使用
RegisterGeneric()
是否可以实现这一点?如果我使用
RegisterAssemblyTypes()
,那么我应该能够使用
Where(type=>type.IsInNamespace(“…”)
,并分别注册每个类型


这是推荐的方法吗?

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

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

public interface IFoo
{ }
namespace X
{
    public class FooX : IFoo { }
}
namespace Y
{
    public class FooY : IFoo { }
}
和1个通用
工厂
和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();
    }
}
公共接口IFooFactory
其中TFoo:IFoo
{
tfoocreate();
}
公共类X工厂:IFooFactory
其中TFoo:IFoo
{
公共TFoo创建()
{
抛出新的NotImplementedException();
}
}
公共类工厂:IFooFactory
其中TFoo:IFoo
{
公共TFoo创建()
{
抛出新的NotImplementedException();
}
}
公共类DefaultFactory:IFooFactory
其中TFoo:IFoo
{
公共TFoo创建()
{
抛出新的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);
            }
        });
ContainerBuilder=newcontainerbuilder();
建造商注册通用(类型(X工厂))
.命名为(“ProjectNamespace.X”,typeof(IFooFactory));
建筑商注册通用(类型(YFactory))
.命名为(“ProjectNamespace.Y”,typeof(IFooFactory));
你的通用工厂是这样的:

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);
            }
        });
builder.RegisterGeneric(typeof(DefaultFactory))
.As(类型(IFooFactory))
.on正在激活(e=>
{
Type elementType=e.Instance.GetType().GetGenericArguments()[0];
Type foodfactorytype=typeof(IFooFactory)。MakeGenericType(elementType);
服务服务=newkeyedservice(elementType.Namespace,fooFactoryType);
Object fooFactory=e.Context.ResolveOptionalService(服务,e.Parameters);
如果(fooFactory!=null)
{
e、 例如(食物制造厂),;
}
});
只有默认工厂注册为
IFooFactory
。如果您尝试解析
IFooFactory
,则激活
on
事件将替换默认的factory实例,您将获得
xfoodfactory


这种方法的主要缺点是每次都会实例化
DefaultFactory
。如果此注册依赖于其他注册,或者初始化需要时间,则可能会出现问题

您说过每次都会实例化
DefaultFooFactory
,我认为您指的是
DefaultFactory
。您是否暗示不会每次都实例化
XFactory
,因为它们不使用
激活
?无论哪种方式,如果我没有弄错的话,
XFactory
都必须在每次需要时通过
on激活
逻辑。这看起来本质上类似于一个抽象工厂,但不是在一个单独的类中实现它,而是在
on activating
中有逻辑,当然可以利用命名注册。工厂的创建和频繁使用成本很高,因此,如果示例中的
XFactory
每次都被实例化,这就不会发生这是个好主意。如果没有,我可以确保
DefaultFactory
永远不会运行,这当然会使该部分变得毫无意义。我可以用这个逻辑来做一个单独的抽象工厂,以避免
DefaultFactory
,但是我必须自己存储实例,并且不能轻松地控制生命周期,这就是Autofac的要点。