子类需要实现接口属性为静态 [英] Subclass needs to implement Interface property as static

查看:119
本文介绍了子类需要实现接口属性为静态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道是否我米甚至逼近这个权利让与裸露的我。我是新的使用界面。



我的意图是,任何API包装项目,我们写在各地的第三方,或者需要一个会话需要(应该由预计的团队模式)实现这个接口,因为它会在这些API封装项目方面加强共性甚至内部API的未来,因为我知道,任何会话班总是会有的getCurrentSession,RenewSession等在他们......因此,我们必须采取具体会话类实现共同的成员方面有统一的模式。



因此,这里的我的界面:

  ///<总结> 
///表示一个API终端用户基于会话
///< /总结>
公共接口IAPISession
{
#区域属性

INT的SessionID {获得;}

///<总结>
///获取用户ID
///注意:string类型,因为用户ID并不总是在第三方的API
诠释///< /总结>
///<价值>将用户ID和LT; /值>
字符串userid {搞定; }

布尔SessionHasExpired {搞定; }

DateTime的到期日期{搞定; }

无效注销(); //到期会话和放大器;设置SessionHasExpired

#endregion属性

#地区的方法

///<总结>
///返回一个全新的会话
///如果现有的会话已过期续订了会议。
///< /总结>
///<&回报GT;< /回报>
IAPISession RenewSession();


///<总结>
///获取当前API会话
///< /总结>
///<&回报GT;< /回报>
IAPISession的getCurrentSession();

#endregion方法
}

下面是一个实现示例

 公共类FacebookSession:IAPISession 
{
私有静态FacebookSession _singletonInstance;

私人FacebookSession(){}

#区域属性

私人的HttpContext CurrentContext {搞定;组; }

私人的HttpCookie CurrentSessionCookie {搞定;组; }

#endregion


#地区IAPISession会员

//检查用于当前会话cookie
公共BOOL SessionHasExpired
{
得到
{
返回_singletonInstance == NULL;
}
}

公共IAPISession RenewSession()
{
抛出新NotImplementedException();
}


///<总结>
///获取当前API会话单一实例
///< /总结>
///<&回报GT;< /回报>
公共静态IAPISession的getCurrentSession()
{
如果(SessionHasExpired)
{
返回NULL;
}

// TODO:在此处返回单一实例...

}

公共无效退出()
{
抛出新NotImplementedException();
}


公众诠释的SessionID {搞定;私人集; }

公共字符串用户名{获得;私人集; }

公共DateTime的到期日期{搞定;私人集; }

#endregion


公共无效登录(HttpContext的currentContext)
{
如果(SessionHasExpired)
{
常量字符串redirectUri =HTTP://localhost/Photo/FacebookOauth.aspx //网页,他们将被重定向到后,他们AUTH
串authUrl = ConfigUtil.GetAppConfigSetting(PayPalBaseUri)+?CLIENT_ID =+
ConfigUtil.GetAppConfigSetting(PayPalClientID)+
与& REDIRECT_URI =+ redirectUri;

CurrentContext.Response.Redirect(authUrl); //重定向他们登录
}
}
}

这是我的问题。会话是当前用户线程单。要访问单,该方法的getCurrentSession()我知道我们创建需要实现(将在如何将根据API实现完全不同的)所有API我需要的属性是静态属性来获取单。



但你不能。因为你不能在一个接口的静态成员。所以...是啊,我可以拿出接口模式的要求,但我真的不想。



FYI这是上面没有的功能代码,我做我的。所有这一切最初的代码,并试图将其最好的设计



更新:



在工厂的话题,让我回过头来给你我在这里做什么更多的上下文。我需要根据我编码什么API包装为得到正确的定制APIService对象(创建为每个API包装服务类工作),所以我创建了一个GetService的工厂(或至少试图to..have不做了很多的工厂),如下图所示。而在这你可以看到所有的方法都是静态的,属性等。



使用示例下面将是:



  FacebookService服务= PhotoServiceFactory.CurrentPhotoUploadServiceFactory; 



的思考?我只是试图做会话相同,但感觉,我想实际上暴露的具体实例时会我从工厂里回来的相关会议。因此,例如我可以做这样的事情:

  service.CurrentSession这会给我目前Facebook的单届。 



这里的服务是FacebookService类型,因为得到它基于API型我厂出去米,工作(API类型是我创建的具有像Facebook,Flickr的等值的枚举。)

 公共类PhotoServiceFactory 
{
私有静态PhotoServiceFactory _singletonInstance;

私人PhotoServiceFactory(){}

#区域属性

公共静态PhotoUploadServiceFactory CurrentPhotoUploadServiceFactory
{
得到
{
_singletonInstance = _singletonInstance? (_singletonInstance =新PhotoUploadServiceFactory());
返回_singletonInstance;
}
}

#endregion

#地区的方法

公共静态IAPIService GetAPIService(APIType apiType)
{
IAPIService apiService = NULL;

开关(apiType)
{
//返回基于我们与
工作API类型正确的服务单一实例
//案例APIType.Facebook:
apiService = FacebookAPIService.CurrentFacebookAPIService;
中断;
情况下APIType.Flickr:
apiService = NULL; //服务没有实现
中断;
情况下APIType.PhotoBucket:
apiService = NULL; //服务没有实现
中断;
情况下APIType.Picasa:
apiService = NULL; //服务没有实现
中断;
情况下APIType.Kodak:
apiService = NULL; //服务没有实现
中断;
}

返回apiService;
}

#endregion
}


解决方案

您可以尝试使用的扩展方法作为接口提供的接口方法的共同实现。你可以在声明同一个命名空间/装配这种扩展方法的接口,这样当有人引用接口,扩展方法将在那里已经为他们使用。在实施中,你可以使用你的单身,这将是一个静态的。

 公共接口IAPIWrapper 
{
字符串userid {搞定; }
布尔SessionHasExpired {搞定; }
DateTime的到期日期{搞定; }
无效注销(); //到期会话和放大器;设置SessionHasExpired

IAPISession RenewSession();
IAPISession的getCurrentSession();
}

公共静态类IAPIWrapperImpl
{
私有静态会话的会话=新的Session(); //实例这里单身

//这是IAPISession RenewSession方法
//第一个参数之前,这个关键字扩展方法使得这种扩展方法
公共静态IAPISession RenewSession(这IAPIWrapper包装)
{
//实现细节
//使用session这里
}

//这是一个扩展方法IAPISession的getCurrentSession方法
//第一个参数之前,这个关键字使得这种扩展方法
公共静态IAPISession的getCurrentSession(此IAPIWrapper包装)
{
//实现细节$ b $这里b //使用session
}
}


I don't know if I"m even approaching this right so bare with me. I'm newer to using Interfaces.

My intent is that any API wrapper projects we write in the future around 3rd party or even internal APIs that need a session will need to (should by expected team pattern) implement this interface because it will enforce commonality in terms of those API Wrapper projects because I know that any session classes will always have GetCurrentSession, RenewSession, etc. in them...so we have a consistent pattern in terms of common members to be implemented for concrete session classes.

So here's my interface:

/// <summary>
/// Represents an API end user based session
/// </summary>
public interface IAPISession
{
    #region Properties

    int SessionID { get; }

    /// <summary>
    /// Gets the user ID.
    /// Note: type string since userID is not always int in 3rd party APIs 
    /// </summary>
    /// <value>The user ID.</value>
    string UserID { get; }

    bool SessionHasExpired { get; }

    DateTime ExpirationDate { get; }

    void LogOut(); // expires the session & sets SessionHasExpired

    #endregion Properties

    #region Methods

    /// <summary>
    /// Renews the session by returning a brand new session 
    /// if the existing session has expired.
    /// </summary>
    /// <returns></returns>
    IAPISession RenewSession();


    /// <summary>
    /// Gets the current API session
    /// </summary>
    /// <returns></returns>
    IAPISession GetCurrentSession();

    #endregion Methods
}

Here is an implementation example:

public class FacebookSession : IAPISession
{
    private static FacebookSession _singletonInstance;

    private FacebookSession() { }

    #region Properties

    private HttpContext CurrentContext { get; set; }

    private HttpCookie CurrentSessionCookie { get; set; }

    #endregion


    #region IAPISession Members

    // Checks for a current session cookie
    public bool SessionHasExpired 
    { 
        get
        {
            return _singletonInstance == null;
        }
    }

    public IAPISession RenewSession()
    {
        throw new NotImplementedException();
    }


    /// <summary>
    /// Gets the current API session singleton instance
    /// </summary>
    /// <returns></returns>
    public static IAPISession GetCurrentSession()
    {
        if (SessionHasExpired)
        {
            return null;
        }

        // TODO: return the singleton instance here...

    }

    public void LogOut()
    {
        throw new NotImplementedException();
    }


    public int SessionID { get; private set; }

    public string UserID { get; private set; }

    public DateTime ExpirationDate { get; private set; }

    #endregion


    public void LogIn(HttpContext currentContext)
    {
        if (SessionHasExpired)
        {
            const string redirectUri = "http://localhost/Photo/FacebookOauth.aspx"; // page they will be redirected to after they auth
            string authUrl = ConfigUtil.GetAppConfigSetting("PayPalBaseUri") + "?client_id=" +
                             ConfigUtil.GetAppConfigSetting("PayPalClientID") +
                             "&redirect_uri=" + redirectUri;

            CurrentContext.Response.Redirect(authUrl); // redirect them to log in
        }
    }
}

and here's my problem. A session is a singleton for the current user thread. To access a singleton, that method GetCurrentSession() which I know all APIs we create will need to implement (will be totally different in HOW they will be implemented based on the API) I need the property to be a static property to get the singleton.

But you can't. Because you can't have static members in an Interface. So...yea I could take out the Interface pattern requirement but I really don't want to.

FYI this is not functional code above, I'm doing my initial coding of all this and trying to design it best.

UPDATE:

On the topic of factories, let me step back to give you more context in what I'm doing here. I needed to get the right custom APIService object (I create a service class for every API wrapper to work with) based on what API wrapper I'm coding for, so I created a GetService factory (or at least attempted to..have not done a lot of factories) like below. And in it you can see that all the methods are static, properties, etc.

Usage example for below would be:

FacebookService service = PhotoServiceFactory.CurrentPhotoUploadServiceFactory;

Thoughts? I'm just trying to do the same for Session but feel I would like to actually expose the related session inside the Specific Service instance that I get back from the factory. So for instance I'd be able to do something like this:

service.CurrentSession which would give me the current facebook singleton session.

The service here is FacebookService type because the factory went out to get it based on the API type I'm working with (API type is an Enum I created that has values like Facebook, Flickr, etc.)

    public class PhotoServiceFactory
    {
        private static PhotoServiceFactory _singletonInstance;

        private PhotoServiceFactory(){}

        #region Properties

        public static PhotoUploadServiceFactory CurrentPhotoUploadServiceFactory
        {
            get
            {
                _singletonInstance = _singletonInstance ?? (_singletonInstance = new PhotoUploadServiceFactory());
                return _singletonInstance;
            } 
        }

        #endregion

        #region Methods

        public static IAPIService GetAPIService(APIType apiType)
        {
            IAPIService apiService = null;

            switch (apiType)
            {
                // return the right service singleton instance
                // based on the API type that we're working with
                case APIType.Facebook:
                    apiService = FacebookAPIService.CurrentFacebookAPIService;
                    break;
                case APIType.Flickr:
                    apiService = null; // service not implemented
                    break;
                case APIType.PhotoBucket:
                    apiService = null; // service not implemented
                    break;
                case APIType.Picasa:
                    apiService = null; // service not implemented
                    break;
                case APIType.Kodak:
                    apiService = null; // service not implemented
                    break;
            }

            return apiService;
        }

        #endregion
    }

解决方案

You could try using Extension methods for interfaces to provide a common implementation for an interface method. You could declare this extension method in the same namespace/assembly as the interface so that when someone references the interface, the extension method will be there already for them to use. In that implementation, you could use your singleton and it would be a static.

public interface IAPIWrapper
{
    string UserID { get; }
    bool SessionHasExpired { get; }
    DateTime ExpirationDate { get; }
    void LogOut(); // expires the session & sets SessionHasExpired

    IAPISession RenewSession();
    IAPISession GetCurrentSession();
}

public static class IAPIWrapperImpl
{
    private static Session session = new Session(); // Instantiate singleton here

    // This is an extension method for the IAPISession RenewSession method
    // the this keyword before the first parameter makes this an extension method
    public static IAPISession RenewSession(this IAPIWrapper wrapper)
    {
         // implementation details
         // use session here
    }

    // This is an extension method for the IAPISession GetCurrentSession method
    // the this keyword before the first parameter makes this an extension method
    public static IAPISession GetCurrentSession(this IAPIWrapper wrapper)
    {
         // implementation details
         // use session here
    }
}

这篇关于子类需要实现接口属性为静态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆