尝试使用引用另一个单例的单例

时间:2010-08-24 21:12:40

标签: c#

我正在调用我创建的自定义工厂(PhotoServiceFactory),这是一个允许我返回特定自定义服务类型的单例(在本例中为FacebookService)。 FacebookService也是一个单身人士。在FacebookService中,我通过一个属性公开了一个FacebookAlbumPhoto实例。我之所以这样做是因为我不需要一遍又一遍地创建一个新的FacebookAlbumPhoto实例......我可以使用FacebookService的属性获取一个实例。

PhotoServiceFactory service = PhotoServiceFactory.CurrentPhotoServiceFactory;
FacebookService facebookService = (FacebookService)service.GetAPIService(APIType.Facebook);

FacebookAlbumPhoto facebookPhoto = facebookService.FacebookAlbumPhoto.GetFacebookAlbumPhoto(selectedPhotoID);

所以现在这一切都已经完成,我创建了所有这些,现在只是测试它。

正在发生的事情是我的代码在这条线上轰炸:

FacebookAlbumPhoto facebookPhoto = facebookService.FacebookAlbumPhoto.GetFacebookAlbumPhoto(selectedPhotoID);

我得到的错误是当我尝试引用facebookService时。 FacebookAlbumPhoto 实例:

  

CurrentSession ='_singletonInstance.CurrentSession'抛出类型'System.Threading.ThreadAbortException'的异常

所以我不知道是不是因为服务单例是在一个线程上,然后它试图引用另一个单独的线程,这是一个完全不同的线程,这是不可能的?那不可能像这样嵌套单身人士吗?或者这可能是另一个问题?因为我看不到它。

这是我的ServiceFactory:

public class PhotoServiceFactory
{
    private static PhotoServiceFactory _singletonInstance;
    private PhotoServiceFactory(){}

    public static PhotoServiceFactory CurrentPhotoServiceFactory
    {
        get
        {
            _singletonInstance = _singletonInstance ?? (_singletonInstance = new PhotoServiceFactory());
            return _singletonInstance;
        }
    }

    public object GetAPIService(APIType apiType)
    {
        object apiService = null;
        switch (apiType)
        {
            case APIType.Facebook:
                apiService = FacebookService.CurrentService;
                break;
            // rest of code
        }

        return apiService;
    }

所以这里的主要单身人士有一个属性来获取其相关的会话:

这是FacebookServiceClass:

public class FacebookService
{
    private static FacebookService _singletonInstance;

    private FacebookService(){}

    public FacebookSession CurrentSession
    {
        get
        {
            return FacebookSession.GetCurrentSession();
        }
    }

    /// <summary>
    /// Gets the current facebook service singleton instance.
    /// </summary>
    /// <value>The current facebook service.</value>
    public static FacebookService CurrentService
    {
        get
        {
            _singletonInstance = _singletonInstance ?? (_singletonInstance = new FacebookService());
            return _singletonInstance;
        }
    }

    public FacebookAlbumPhoto FacebookAlbumPhoto
    {
        get
        {
            return new FacebookAlbumPhoto(); // create an instance automatically so we can start working with this object
        }
    }
}

以下是会话类:

public class FacebookSession
{
    const string loginCallbackUrl = "http://localhost/PhotoUpload/FacebookOauth.aspx";

    private FacebookSession()
    {
    }

    public string UserID { get; private set; }

    public static FacebookSession GetCurrentSession()
    {
        //....bunch of other logic is here
        FacebookSession facebookSession = CreateNewSession();
        return facebookSession;
    }

    public FacebookSession CreateNewSession()
    {
        //...some code here
        FacebookSession newFacebookSession = new FacebookSession
        //... rest of code...
        return newFacebookSession;
    }
    // ... rest of code
}

更新:

根据我的要求,这是我创建的FacebookAlbumPhoto课程:

    public class FacebookAlbumPhoto : FacebookPhotoBase
    {
        private FacebookSession currentSession;

        public FacebookAlbumPhoto()
        {
            currentSession = FacebookService.CurrentService.CurrentSession;             
        }

        #region Methods

        public FacebookAlbumPhoto GetFacebookAlbumPhoto(string photoID)
        {
            ...more code
             FacebookPhotoRequest request = new FacebookPhotoRequest(currentSession.UserID, photoID);
            ...more code

            FacebookAlbumPhoto facebookPhoto = ParseFacebookPhoto(json);

            return facebookPhoto;
        }
...rest of code
}

2 个答案:

答案 0 :(得分:1)

两件事。首先,请记得阅读Skeet's catalogue of singleton implementations。 其次,尝试在发生异常的位置之前破坏代码,然后调出“异常”对话框(ctrl-alt-e)。单击CLR旁边的“throw”复选框(第二行对话框),然后单击确定。继续调试您的代码。结果可能会告诉您真正的问题在哪里。

完成后,请不要忘记返回“异常”对话框并从复选框中删除该检查。 :)

答案 1 :(得分:0)

将实例创建与初始化分开