Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# 克隆现有的AutoFac对象(一次注册除外)_C#_Inversion Of Control_Autofac - Fatal编程技术网

C# 克隆现有的AutoFac对象(一次注册除外)

C# 克隆现有的AutoFac对象(一次注册除外),c#,inversion-of-control,autofac,C#,Inversion Of Control,Autofac,假设我在AutoFac中注册了以下内容(简化): 对象A-->对象B-->对象C-->对象D 现在假设我想创建第二个对象a(我们称之为对象p),它是对象a的虚拟克隆,除了一个区别: 对象A-->对象B-->对象F-->对象D 是否有办法获取现有的AutoFac对象并以这种方式克隆它?我在“真实生活”中使用的对象图比这个例子复杂很多数量级,如果没有必要,我宁愿不复制一堆注册逻辑。虽然你可能会疯狂/幻想使用它来实现这一点,最简单的方法是使用嵌套的生存期范围和覆盖注册 当您开始一个新的生存期作用域时,

假设我在AutoFac中注册了以下内容(简化):

对象A-->对象B-->对象C-->对象D

现在假设我想创建第二个对象a(我们称之为对象p),它是对象a的虚拟克隆,除了一个区别:

对象A-->对象B-->对象F-->对象D


是否有办法获取现有的AutoFac对象并以这种方式克隆它?我在“真实生活”中使用的对象图比这个例子复杂很多数量级,如果没有必要,我宁愿不复制一堆注册逻辑。

虽然你可能会疯狂/幻想使用它来实现这一点,最简单的方法是使用嵌套的生存期范围和覆盖注册

当您开始一个新的生存期作用域时,您可以传入一个lambda表达式,该表达式允许您动态地向该作用域添加新的注册。此时,您将用“对象F”覆盖“对象C”注册

这里有一个有效的例子。首先,让我们定义一些接口和实现。您会注意到层次结构中的第三个服务,
ITIRD
,有两个实现-
ObjectC
ObjectF
,以匹配您的问题:

public interface IFirst
{
    ISecond Child { get; }
    void WriteHierarchy();
}

public interface ISecond
{
    IThird Child { get; }
}

public interface IThird
{
    IFourth Child { get; }
}

public interface IFourth
{
}

public class ObjectA : IFirst
{
    public ObjectA(ISecond child)
    {
        this.Child = child;
    }

    public ISecond Child { get; private set; }

    public void WriteHierarchy()
    {
        Console.WriteLine("{0} -> {1} -> {2} -> {3}",
            this.GetType().Name,
            this.Child.GetType().Name,
            this.Child.Child.GetType().Name,
            this.Child.Child.Child.GetType().Name);
    }
}

public class ObjectB : ISecond
{
    public ObjectB(IThird child)
    {
        this.Child = child;
    }

    public IThird Child { get; private set; }
}

public class ObjectC : IThird
{
    public ObjectC(IFourth child)
    {
        this.Child = child;
    }

    public IFourth Child { get; private set; }
}

public class ObjectF : IThird
{
    public ObjectF(IFourth child)
    {
        this.Child = child;
    }

    public IFourth Child { get; private set; }
}

public class ObjectD : IFourth
{
}
有了它,您可以看到我们将要做的是解析顶级项,
IFirst
,然后我们将写出层次结构

下面是显示层次结构中第三项的“交换”的实际工作代码:

var builder = new ContainerBuilder();
builder.RegisterType<ObjectA>().As<IFirst>();
builder.RegisterType<ObjectB>().As<ISecond>();
builder.RegisterType<ObjectC>().As<IThird>();
builder.RegisterType<ObjectD>().As<IFourth>();

var container = builder.Build();

// It's always good to use lifetime scopes and not
// resolve directly from a container. You can see
// here that I'm not doing anything special - this
// lifetime scope will have the "default registrations."
using(var scope = container.BeginLifetimeScope())
{
    // This will print:
    // ObjectA -> ObjectB -> ObjectC -> ObjectD
    var obj = scope.Resolve<IFirst>();
    obj.WriteHierarchy();
}

// You can pass override registrations when you begin
// a new lifetime scope. In this case, I'm overriding
// the one service type deep in the hierarchy.
using(var scope = container.BeginLifetimeScope(
    b => b.RegisterType<ObjectF>().As<IThird>()))
{
    // This will print:
    // ObjectA -> ObjectB -> ObjectF -> ObjectD
    var obj = scope.Resolve<IFirst>();
    obj.WriteHierarchy();
}
var builder=newcontainerbuilder();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
builder.RegisterType().As();
var container=builder.Build();
//使用生存期作用域总是好的,而不是
//直接从容器解析。你可以看到
//在这里,我没有做任何特别的事情-这个
//生存期范围将具有“默认注册”
使用(var scope=container.BeginLifetimeScope())
{
//这将打印:
//ObjectA->ObjectB->ObjectC->ObjectD
var obj=scope.Resolve();
obj.WriteHierarchy();
}
//开始时可以传递覆盖注册
//新的生命周期范围。在这种情况下,我将覆盖
//层次结构中最深层的一种服务类型。
使用(var scope=container.BeginLifetimeScope)(
b=>b.RegisterType().As())
{
//这将打印:
//ObjectA->ObjectB->ObjectF->ObjectD
var obj=scope.Resolve();
obj.WriteHierarchy();
}

您是想从同一个容器中解析不同的对象图,还是想找出一种方法,在两个不同的容器中重复使用尽可能多的对象注册?前者。我只处理一个集装箱,嗨,特拉维斯。非常感谢你的例子。我很难将其转化为需求。我使用的不是服务定位器,因此需要克隆对象A的对象无法访问AutoFac容器。您不会从对象图中创建生存期范围,而是在工作单元的最顶端创建它。不幸的是,我不能在这方面给你具体的指导——你必须将模式应用到你独特的需求中。