传递上下文对象的替代方法

时间:2013-09-04 12:35:56

标签: c#

我有一个上下文对象,我希望能够从大量的差异类中访问。我的代码看起来像

Context ctx = new Context();
Section section = new Section(ctx) {
    Data1 = new SomeData(ctx) { Value = 123 },
    Data2 = new SomeOtherData(ctx) { Foo = "bar" },
    SubSection = new Section(ctx) {
        MoreData = new MoreData(ctx) { Text = "Hello!" }
    }
};

但我真正喜欢的是代码如下:

using(Context.New()) {
    Section section = new Section() {
        Data1 = new SomeData { Value = 123 },
        Data2 = new SomeOtherData { Foo = "bar" },
        SubSection = new Section {
            MoreData = new MoreData { Text = "Hello!" }
        }
    };
    // do something with section
}

这可能吗?我将在ASP.NET和.exes中使用它(以及将来可能还有其他东西),所以我不能只在某处存储static或线程本地引用。

它不需要完全如上所述,只是我不必将上下文传递给我创建的每个对象。我考虑使用像context.createSomeData()这样的扩展方法,但是每个类需要更多的样板,并且因为你仍然需要上下文对象而不是更好。

理想情况下应该在VS2008 / .NET3.5下工作,尽管如果有任何办法我仍然感兴趣。

更新:我最终通过将我的方法重构为以下内容来解决这个问题:

Section section = new Section {
    Data1 = new SomeData { Value = 123 },
    Data2 = new SomeOtherData { Foo = "bar" },
    SubSection = new Section {
        MoreData = new MoreData { Text = "Hello!" }
    }
};
section.DoStuffWithContext(new Context());

虽然它可能对每个人都不起作用,但它确实符合我的需要。

如果有人为最初的问题提出了一个很好的解决方案,我会把这个问题保留下来。

3 个答案:

答案 0 :(得分:2)

您可以定义静态方法Context.RetreiveData(),但不必在方法本身内部实现任何样板代码。

使用命令模式,每个特定项目类型都可以为RetreiveData()方法提供自己的实现。 ASP.NET项目可以提供一种可以从Session中检索数据的方法。 WinForm可执行文件可以提供一种方法,可以从某个全局变量中检索数据。另一个项目可以提供一种从DB中检索数据的方法。

答案 1 :(得分:1)

没有。没有任何明确的可能性。您甚至使用对象初始值设定项(new Obj { ... }),因此您需要使用new运算符(这使得无法使用ctx的静态方法/扩展方法)。

你唯一能做的就是:

SomeData MakeSomeData(this Context ctx, int value)
{
    return new SomeData(ctx) { Value = value };
}

并在初始化中:

Context ctx = new Context();

Section section = new Section(ctx) {
    Data1 = ctx.MakeSomeData(123), ...

但我认为你不会得到任何东西

答案 2 :(得分:0)

我对您的问题发表了第二次 hvd 评论,我认为这不需要太多样板。假设每个类都实现了这个:

public interface IContextConsumer {
    Context Context { get; set; }
}

你的基类有这样的方法:

protected void AddChild(IContextConsumer child) {
    child.Context = this.Context;
}

属性实现只需要:

private SomeData _data1;
public SomeData Data1 {
    get { return _data1; }
    set {
        _data1 = value;
        AddChild(_data1);
    }
}

如果您执行了类似的操作,甚至可以允许在根目录上重新分配上下文:

protected void AddChild(IContextConsumer child) {
    Children.Add(child);
    child.Context = this.Context;
}

protected void OnContextChanged() {
    foreach (var child in Children) child.Context = this.Context;
}

派生类只需要在OnContextChanged属性实现中调用Context