避免全局状态

本文关键字:状态 全局 | 更新日期: 2023-09-27 18:24:20

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

此外,假设有时我们可能需要从其他地方的这个SecureOperationContext中知道某个属性,在一个存在和不会存在这个SecureOperation Context的地方。例如,用于某种日志记录目的的用户名。

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

现在,在一些"Common"库中,有一个用ThreadStatic属性定义的类:Username。我想你可以理解我的想法:安全性设置了这个静态全局变量,你瞧,我们有它可以用来记录puprose。

这件事让我很烦恼,但另一方面,还能做什么呢?我想创建一个以字符串为参数的方法来处理这个问题,但我的所有方法仍然需要读取username属性,它是非干的。因此,一方面,通过这种方式,一切都是在后台处理的,但为了实现这一点,我不仅很高兴不得不维护一些(全局)类。

有什么建议吗?

我不知道如何用不那么抽象的术语来表达,但这里是(伪)。

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是不可取的,因为我们仍然需要手动为所有内容重新分配用户名,这很糟糕。

避免全局状态

封装服务中的全局属性。为该服务定义一个接口。现在,在任何需要数据的地方都依赖该接口,方法是使用该类型的构造函数参数。

这被称为依赖注入,当你想避免目前的问题时,这是一个非常重要的概念。如果您有一个大型应用程序,那么像Autofac这样的依赖注入容器会有所帮助,但这并不是严格要求的。

最重要的是理解依赖注入,并拥有定义良好的组合根,无论您是使用DI容器还是自己动手

安全性设置了这个静态全局变量,瞧,我们有它可以用来记录puprose。

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

编辑:您可以通过工厂创建客户端对象来进一步改进设计。该工厂可以确保值是可用的,因此它将客户端对象的生存期与值的可用性相耦合。通过这种方式,您可以确保始终在可以安全访问值的上下文中进行操作。