我有一個Skype Bot服務,它具有用於縮短給定url的已定義接口。如何使用Ninject上下文綁定綁定多個實現
namespace Skypnet.Modules.UrlShortener
{
public interface IUrlShortenerProvider
{
string ApiKey { get; set; }
string Shorten(string url);
}
}
該接口由兩個服務實現,一個使用Google Url縮短API,另一個使用TinyUrl API。
我的機器人在啓動時會加載多個模塊,每個模塊都會在SKype客戶端上註冊監聽事件。所以,當我的Skype發送消息:
Patrick Magee>!tiny http://example.com/a-really-long-url-that-i-want-to-shorten
然後,我已經聽了消息事件,並分析了我的信息註冊模塊檢查它是否驗證對他們是什麼那裏做,他們執行與返回一個小網址的消息。
Patrick Magee> Bot> http://tinyurl.com/2tx
以略高的水平,我有一個定義的抽象Skypenet模塊,所有模塊Skypenet必須實現。
public class UrlShortenerSkypnetModule : AbstractSkypenetModule
這個抽象模塊的唯一重要的事情是,它可以讓我UrlShortner註冊其爲Skype事件,像這樣:
public class UrlShortenerSkypnetModule : AbstractSkypenetModule
{
private readonly IUrlShortenerProvider urlShortenerProvider;
private const string RegexPatternV2 = @"^!(?<command>tiny)\s+(?<service>\S+?)\s+(?<url>(?<protocol>(ht|f)tp(s?))\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*))";
//private const string RegexPattern = @"^!(?<command>tiny)\s+(?<url>(?<protocol>(ht|f)tp(s?))\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*))";
private static readonly Regex UrlRegex = new Regex(RegexPatternV2, RegexOptions.Compiled);
/// <summary>
/// The Trigger used for this url shortener provider
/// </summary>
[Inject]
public string Trigger { get; set; }
[Inject]
public UrlShortenerSkypnetModule(IUrlShortenerProvider urlShortenerProvider)
{
if (urlShortenerProvider == null)
throw new ArgumentNullException("urlShortenerProvider");
this.urlShortenerProvider = urlShortenerProvider;
}
public override void RegisterEventHandlers()
{
SkypeContainer.Skype.MessageStatus += SkypeOnMessageStatus;
}
private void SkypeOnMessageStatus(ChatMessage pMessage, TChatMessageStatus status)
{
if (status == TChatMessageStatus.cmsSent || status == TChatMessageStatus.cmsReceived)
{
Match match = UrlRegex.Match(pMessage.Body);
if (match.Success)
{
var url = match.Groups["url"].Value;
var trigger = match.Groups["service"].Value;
// If the service matches
if (trigger.ToLower().Equals(Trigger.ToLower()))
{
string shorten = urlShortenerProvider.Shorten(url);
pMessage.Chat.SendMessage(shorten);
}
}
}
}
}
如何使用Ninject模塊綁定兩個URL提供給相同的父級抽象模塊並基於其名稱將不同的IUrlShortenerProvider注入該實例。除此之外,這是否是正確的方式呢?
public class TinyUrlProvider : IUrlShortenerProvider
public class GoogleUrlProvider : IUrlShortenerProvider
這樣既實現是實例化,如果實現匹配 一個觸發字,如「谷歌」或我UrlShortnerskypenetModule
可以定義「TinyURL的」,相應的實例處理請求?
到目前爲止,我有一個NinjectModul
E對於我UrlShortenerModule
它看起來像這樣,但它是完全錯誤的,但希望給出了什麼,我想acomplish
public class UrlShortenerModules : NinjectModule
{
public override void Load()
{
// The Abstract Module which all Modules must implement
Bind<ISkypnetModule>()
.To<AbstractSkypenetModule>()
.Named("UrlShortener")
.WithPropertyValue("Name", "Minify")
.WithPropertyValue("Description", "Produces a minified url of a given url.")
.WithPropertyValue("Instructions", "!tiny [service] [url] i.e '!tiny google http://example.com/a-really-long-url-you-want-to-minify'");
// Well we have a Google url service
// but i want this service to have the same abstract parent
// as the tinyurl service - since both are part of the minify module
Bind<ISkypnetModule>()
.To<UrlShortenerSkypnetModule>()
.WhenParentNamed("UrlShortener")
.Named("Google")
.WithPropertyValue("Trigger", "google");
// We also have a tiny url service
// but i want this service to have the same abstract parent
// as the google service - since both are part of the minify module
Bind<ISkypnetModule>()
.To<UrlShortenerSkypnetModule>()
.WhenParentNamed("UrlShortener")
.Named("Tinyurl")
.WithPropertyValue("Trigger", "tinyurl");
// Well the tiny url provider should be injected
// into urlshortener named tinyurl
Bind<IUrlShortenerProvider>()
.To<TinyUrlProvider>()
.WhenParentNamed("Tinyurl")
.WithPropertyValue("ApiKey", "");
// Well the google url service should be injected
// into urlshortener named google
Bind<IUrlShortenerProvider>()
.To<GoogleUrlProvider>()
.WhenParentNamed("Google")
.WithPropertyValue("ApiKey", "");
}
}
瞭解我見過的某種與Spring.NET配置類似的行爲,您可以在Spring.config中定義對象並將abstract =「true」並將其聲明爲父對象,然後讓兩個對象具有相同的父抽象對象。我相信這就是我所追求的,但我從來沒有這麼做過設置容器和依賴注入。
好走帕特里克,起初我還以爲您的解決方案過於複雜,你可以使用一個簡單的查找字典, 但使用Ninject會自己做幫助您更輕鬆地測試解決方案並更好地管理依賴關係。 – 2013-05-11 14:18:13
感謝您的關注! – 2013-05-11 14:22:43