C# - 静态方法或在使用第三方库时创建新实例

时间:2018-06-06 06:22:10

标签: c# asp.net .net asp.net-mvc asp.net-web-api

我有一个只实现第三方库的课程 - 我可以告诉你这是Google Cloud

我想知道在使用这种库时,如何正确使用它?

以下是我的示例,说明我如何使用:

新实例

声明

public class MyClass{
        private readonly string _jsonPath= ...;

        public readonly StorageClient Client;

        public MyClass()
        {
            var credential = GoogleCredential.FromFile(_jsonPath);
            Client = StorageClient.Create(credential);
        }

        public string Upload(/*my parameter*/)
        {
            Client.UploadObject(...);
            // etc
        }
}

用法

var myInstance = new MyClass();

myInstance.Upload(...);

静态方法

声明

public class MyClass{
        private static readonly string _jsonPath= ...;

        public static readonly StorageClient Client = StorageClient.Create(GoogleCredential.FromFile(_jsonPath));

        public static string Upload(/*my parameter*/)
        {
            Client.UploadObject(...);
            // etc
        }
}

用法

MyClass.Upload(...);

由于这些方法会经常被同时调用,我想知道哪种用法更好,为什么要避免问题。

据我所知,静态不擅长共享同一个班级成员,

但我认为每次我需要使用时声明客户端都是多余的。

我想更多地了解这两种方式的优点和缺点。

任何建议都将受到赞赏。

我的英语非常基础,请不要介意。

感谢您的阅读。

3 个答案:

答案 0 :(得分:2)

您可以使用静态类来经常使用组件。但我建议您在此过程中使用单例设计模式。

答案 1 :(得分:2)

根据您的MyClass要求,这有点难以回答。 MyClass做什么?它需要一些设置吗?建造? Upload方法是否依赖于实例状态?

我通常喜欢注入我的外部依赖项,并将它们隐藏在接口后面。这样我就可以创建测试双打,并且如果我愿意,可以轻松更改依赖项。我倾向于不喜欢使用静态,除非它适用于无状态实用程序类,如数学,字符串操作,扩展和其他无状态处理。

对于需要状态的东西,我使用实例。如果我真的需要共享状态,我会使用单例,但如果可能的话我尽量避免使用它们。

在您的情况下,我将创建一个IStorageProvider,实现一个GoogleCloudStorageProvider,并将IStorageProvider的依赖项放在MyClass上。

public class MyClass {
    IStorageProvider Storage;
    public MyClass(IStorageProvider storage)
    {
        Storage = storage;
    }
    public async void Upload(Data data){
        await Storage.Save(data);
    }
}

public interface IStorageProvider{
    void Upload(Data data);
}

public class GoogleCloudStorage:IStorageProvider{
    private Credentials Creds;
    private GoogleCloudClient Client;
    public GoogleCloudStorage(Credentials creds)
    {
        Creds = creds;
        Client = new GoogleCloudClient();
    }

    private void Connect(){
        Client.Connect(Creds);
    }
    public async void Upload(Data data){
        if(!Client.Connected){
            Connect();
        }
        return await Client.Upload(data);
    }
}

我觉得这种方法更灵活。

答案 2 :(得分:1)

我会使用您的第一种方法并将您的Upload方法更改为异步,以便可以同时运行独立任务。使用第二种方法,您可以使用两个不同的线程,这些线程以非线程安全的方式更改同一个对象。

做这样的事情:

public class MyClass{

    private readonly string _jsonPath= ...;
    private readonly StorageClient _storageClient;

    public MyClass()
    {
        var credential = GoogleCredential.FromFile(_jsonPath);
        _storageClient = StorageClient.Create(credential);
    }

    public Task<string> UploadAsync(/*my parameter*/)
    {
        var imageObject = await _storageClient.UploadObjectAsync(...);
        // etc
    }
}