如何在不滥用静态方法的情况下从任何位置访问对象?

时间:2019-04-23 21:45:09

标签: c# design-patterns data-structures architecture software-design

此问题与桌面应用程序有关。

我一直在思考的事情是一种能够访问可能被视为全局对象的方法,例如将其声明为静态对象。但是我总是避免这种情况。

例如,在应用程序中,经常会出现一个User对象(或类似对象)。想象一下从业务逻辑的某个地方使用了数据模型/存储库,您需要用户ID将其作为参数传递给数据层,以便它可以为用户加载相应的数据。 在Web应用程序中,大多数时候我都会看到诸如用户ID之类的信息来自URL参数或HTTP发布数据,并通过其action方法发送到控制器中。

在桌面应用程序中,这是不同的,因为所有“状态”保持不变。假设一个用户对象在程序启动时被构造一次,当然现在已经存储在内存中的某个地方。如何从应用程序的另一部分访问它?似乎只有两个选项:

  1. 在包含用户对象的常规类上使用静态方法,该方法将返回该对象。
  2. 通过整个类树注入用户对象 需要对象。

我认为这两种选择都是丑陋的,不是最佳选择。既然我认为这是非常普遍的情况,那么保持良好结构的最佳实践是什么?

2 个答案:

答案 0 :(得分:0)

我不确定为什么您认为#2是“丑陋的而不是最优的”,但是不是注入User对象,而是注入具有获取当前用户对象方法的IUserService,是一种考虑的方法。

我已经在各种使用Microsoft Unity的桌面应用程序中完成了类似的操作,但是在各种DI框架上您可以考虑很多选择。我不确定您一般对DI的熟悉程度,并且那里有大量文章,但是我发现这个概念的一个不错的起点是Microsoft patterns & practices Developer Center,其中包含关于Unity的一些入门文档,当然,Git Hub上的最新Unity Container Documentation

如果您对如何实现这种模式有特定疑问,请发表另一篇文章。

答案 1 :(得分:0)

我猜您正在使用被称为桌面应用程序的WinForms或WPF应用程序。如果是这样,您肯定可以利用许多IoC容器之一以全局方式存储对象,然后在需要时访问它。但是,对于简单的场景,我认为这是不值得的。

一个简单的解决方案是使用静态工厂,该工厂可以在需要时创建对象,或者将其存储为静态对象,以便在整个应用程序中都可用,前提是其状态保持不变。您可以添加通用方法以返回类型为T的对象,也可以添加特定方法来创建可能需要某些逻辑的对象。

public static class ObjectFactory
{
    public static T GetObject<T>() where T : new()
    {
        return new T();
    }

    public static User GetUserObject(param1, param2)
    {
        // some logic
        ....
        return new User();
    }
}

如果不需要每次都创建对象,则可以修改以上代码以将其也存储在字典中。请确保,不要在字典中使内存中存储的对象过多,或者如果不需要的话,也可以添加删除对象的方法。

public static class ObjectFactory
{
    private static Dictionary<string, object> collection = new Dictionary<string, object>();

    public static T GetObject<T>() where T : new()
    {
        string key = typeof(T).ToString();

        if (collection.ContainsKey(typeof(T).ToString()))
            return (T)collection[key];

        var instance = new T();

        collection.Add(key, instance);

        return instance;
    }
}

在桌面应用程序中使用IoC框架的问题是,它们没有像Web应用程序那样类似的应用程序生存期。一旦启动应用程序,就不会出现类似请求/响应的情况。您将显示可能可以打开其他表单的主表单,依此类推。

如果您正在寻找更复杂的解决方案,其中涉及解决表单实例以及相关性。请查看answer(可能重复的问题)。

我希望这会有所帮助。