避免全局状态

Avoid a global state

想象一下 SOA。我们有一些不同的服务,其中 OperationContext 由一些 SecureOperationContext 扩展,确保满足某些安全需求。

进一步假设有时我们可能需要从其他地方的这个 SecureOperationContext 知道某个 属性,在一个有也不会有这个 SecureOperationContext 的地方。例如用于某种记录目的的用户名。

目前我们使用的东西看起来和闻起来都很脏。脂肪在我看来滴滴滴。

现在,在某些 'Common' 库中,有一个 class 定义了一个 ThreadStatic 属性: 用户名。我猜你能理解我的意思:安全性的东西设置了这个静态全局变量,你看我们有它可用于记录 puproses。

这件事让我很烦恼,但另一方面还能做什么?我正在考虑创建一个将字符串作为参数来处理这个问题的方法,但是我的所有方法仍然需要读取该用户名 属性,这是非干的。 因此,一方面,通过这种方式,一切都在后台处理,但我不只是为了实现这一点而不得不维护一些(全局)class。

有什么建议吗?

我不确定如何用不太抽象的术语来表达它,但这里是(伪)。

public WebService
{
    public Save(Car car)
    {
        // Some SecurityCOntext is known here, this holds top secret info, 
         //  like the username
        // and sets this into the golbal helper class UserNameManagemer 

        // car has for example a CreatedDate property (from an Interface),   
        //but I don't want handle do this propertyin every Create method can handled in some general piecei of code.       


        efcontainer.AddObjcect(car)
        e.SaveChanges()  -> 
        //Now savechanges will check the objects in the ObjectSatateManager 
        //and sets the apppriopriate property via the global thing.
    }
}

现在该怎么做才能摆脱这个全局变量!。将用户名传递给 SaveChanges 也是不可取的,因为我们仍然必须为所有内容手动重新设置它,这很糟糕。

将全局 属性 封装在一个服务中。为该服务定义一个接口。现在,在任何需要数据的地方都依赖于该接口 通过具有该类型的构造函数参数 .

如果您有大型应用程序,这称为 dependency injection and is a very important concept when you want to avoid problems as the one you currently have. A dependency injection container such as Autofac 可以提供帮助,但不是严格要求。

最重要的是理解依赖注入,有一个明确的定义composition root,不管是用DI容器还是自己做

The security stuff sets this static global variable and lo and behold we have it available for logging puproses.

这听起来像是数据是动态确定的。请注意,您仍然可以使用服务来跟踪该值。该服务还知道该值是否可用。这样,您可以更好地管理当前的时间耦合。

编辑:您可以通过工厂创建客户端对象来进一步改进设计。该工厂可以确保该值可用,因此它将客户端对象的生命周期与该值的可用性联系起来。这样,您一定会始终在可以安全访问值的上下文中操作。