2

特定の URL を短縮するためのインターフェイスが定義された Skype ボット サービスがあります。

namespace Skypnet.Modules.UrlShortener
{
    public interface IUrlShortenerProvider
    {
        string ApiKey { get; set; }
        string Shorten(string url);
    }
}

このインターフェイスは、Google Url 短縮 API を使用するサービスと TinyUrl API を使用するサービスの 2 つのサービスによって実装されます。

私のボットは起動時に複数のモジュールをロードし、各モジュールは SKype クライアントでリッスン イベントを登録します。Skype でメッセージを送信すると、次のようになります。

Patrick Magee>!tiny http://example.com/a-really-long-url-that-i-want-to-shorten 

次に、メッセージイベントをリッスンし、メッセージを分析して、メッセージが何をすべきかに対して検証されるかどうかを確認した登録済みモジュールが実行され、小さなURLのメッセージが返されます。

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\-\.\?\,\'\/\\\+&amp;%\$#_]*))";
    //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\-\.\?\,\'\/\\\+&amp;%\$#_]*))";
    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

両方の実装がインスタンス化され、実装が「google」や「tinyurl」などのトリガーワードに一致する場合UrlShortnerskypenetModule、適切なインスタンスがリクエストを処理するようにしますか?

これまでのところ、私はこのように見えるNinjectModul私の eを持ってUrlShortenerModuleいますが、それは完全に間違っていますが、うまくいけば、私が達成しようとしていることを理解することができます

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.config でオブジェクトを定義し、abstract="true" を持ち、それを親オブジェクトとして宣言し、同じ親抽象オブジェクトを持つ 2 つのオブジェクトを持つことができる Spring.NET 構成で、ある種の同様の動作を見てきました。これが私が求めていることだと思いますが、コンテナーと依存性注入のセットアップにここまで行ったことはありません。

4

1 に答える 1

1

私の答えで宣言した方法が正しい方法のようです。したがって、答えは複数のバインディングを宣言することです。これにより、同じ SkypenetModule で機能する新しいインスタンスが作成されます。どちらも .Named UrlShortenerSkypenetModule に基づいてインスタンス化されるため

    Bind<ISkypnetModule>()
        .To<UrlShortenerSkypnetModule>()
        .WhenParentNamed("UrlShortener")
        .Named("Google")
        .WithPropertyValue("Trigger", "google");


    Bind<ISkypnetModule>()
        .To<UrlShortenerSkypnetModule>()
        .WhenParentNamed("UrlShortener")
        .Named("Tinyurl")
        .WithPropertyValue("Trigger", "tinyurl");


    Bind<IUrlShortenerProvider>()
        .To<TinyUrlProvider>()
        .WhenParentNamed("Tinyurl")
        .WithPropertyValue("ApiKey", "");


    Bind<IUrlShortenerProvider>()
        .To<GoogleUrlProvider>()
        .WhenParentNamed("Google")
        .WithPropertyValue("ApiKey", "");
于 2013-05-11T03:42:18.443 に答える