只处理初始化对象?

时间:2016-01-07 21:36:29

标签: c# .net dispose

我有一个API包装器,它具有一系列在首次使用时初始化的属性。当调用类的Disposed方法时,它会处理它存储的所有其他类。但是,很有可能只有其中一个或两个类已初始化。如果这些类尚未初始化,Dispose方法实际上最终会初始化它们并将它们处理掉。这是一个庞大的资源和时间密集型,但我想不出一种方法来补救它。

这是班级。

public class SalesForceApi : ISalesForce, IDisposable
{
    public Logger Logger = LogManager.GetCurrentClassLogger();

    private IAccounts _accounts;
    private IAttachments _attachments;
    private ICases _cases;
    private IContacts _contacts;
    private IGroups _groups;
    private IRecordTypes _recordTypes;
    private IUsers _users;

    public IAccounts Accounts => _accounts ?? (_accounts = new Accounts());

    public IAttachments Attachments => _attachments ?? (_attachments = new Attachments());
    public ICases Cases => _cases ?? (_cases = new Cases());
    public IContacts Contacts => _contacts ?? (_contacts = new Contacts());
    public IGroups Groups => _groups ?? (_groups = new Groups());
    public IRecordTypes RecordTypes => _recordTypes ?? (_recordTypes = new RecordTypes());
    public IUsers Users => _users ?? (_users = new Users());

    public SalesForceApi()
    {

    }

    public void Dispose()
    {
        Logger.Trace("Disposing of Acccounts...");
        Accounts.Dispose();
        Logger.Trace("Disposing of Attachments...");
        Attachments.Dispose();
        Logger.Trace("Disposing of Cases...");
        Cases.Dispose();
        Logger.Trace("Disposing of Contacts...");
        Contacts.Dispose();
        Logger.Trace("Disposing of Groups...");
        Groups.Dispose();
        Logger.Trace("Disposing of RecordTypes...");
        RecordTypes.Dispose();
        Logger.Trace("Disposing of Users...");
        Users.Dispose();
    }
}

以下是生成的日志的样子:

SalesForceApi_v1.SalesForceApi::Disposing of Acccounts...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Attachments...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Cases...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Contacts...
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Groups...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of RecordTypes...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce.
SalesForceApi_v1.SalesForceApi::Disposing of Users...
SalesForceApi_v1.Requests.RequestBase::Logging into SalesForce...
SalesForceApi_v1.Requests.RequestBase::SalesForce login successful!
SalesForceApi_v1.Requests.RequestBase::Logging out of SalesForce. 

3 个答案:

答案 0 :(得分:5)

处置时,不要调用lazy-init的方法;测试并处理私有成员变量(_accounts等)。

答案 1 :(得分:3)

不要在Dispose方法中使用属性,请使用私有字段。

public void Dispose()
{
    Logger.Trace("Disposing of Acccounts...");
    if(_accounts != null) _accounts.Dispose();
    Logger.Trace("Disposing of Attachments...");
    if(_attachments != null) _attachments.Dispose();
    // ...
}

答案 2 :(得分:0)

您可以将您的处置包装在私人成员空检查中。由于你是延迟加载,调用Property.Dispose()实际上创建了一个类的实例,只是为了处理它。我还想在处理后将我的成员设置为null,以便在我尝试再次访问它时它会抛出NullReferenceException。

public void Dispose()
{
    if (_accounts != null) 
    {
        Logger.Trace("Disposing of Acccounts...");
        Accounts.Dispose();
        // or
        // _accounts.Dispose();
        // _accounts = null;
    }
    if (_attachments != null) 
    {
        Logger.Trace("Disposing of Attachments...");
        Attachments.Dispose();
        // or
        // _attachments.Dispose();
        // _attachments = null;
    }
    if (_cases != null) 
    {
        Logger.Trace("Disposing of Cases...");
        Cases.Dispose();
        // or
        // _cases.Dispose();
        // _cases= null;
    }
    if (_contacts != null) 
    {
        Logger.Trace("Disposing of Contacts...");
        Contacts.Dispose();
        // or
        // _contacts.Dispose();
        // _contacts = null;
    }
    if (_groups != null) 
    {
        Logger.Trace("Disposing of Groups...");
        Groups.Dispose();
        // or
        // _groups.Dispose();
        // _groups = null;
    }
    if (_recordTypes != null) 
    {
        Logger.Trace("Disposing of RecordTypes...");
        RecordTypes.Dispose();
        // or
        // _recordTypes.Dispose();
        // _recordTypes = null;
    }
    if (_users!= null) 
    {
        Logger.Trace("Disposing of Users...");
        Users.Dispose();
        // or
        // _users.Dispose();
        // _users= null;
    }
}