2013-04-27 1 views
2

주어진 URL을 줄이기 위해 정의 된 인터페이스가있는 Skype Bot 서비스가 있습니다.Ninject 컨텍스트 바인딩을 사용하여 여러 구현을 바인딩하는 방법

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

이 인터페이스는 Google URL 단축 API를 사용하는 서비스와 TinyUrl API를 사용하는 두 가지 서비스로 구현됩니다.

내 봇은 시작시 여러 모듈을로드하고 각 모듈은 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 모듈이 구현해야하는 정의 된 Abstract Skypenet Module이 있습니다.

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); 
       } 
      } 
     } 
    } 
} 

어떻게 내가에게 모두 URL 제공 업체를 결합하는 Ninject에 모듈을 사용할 수 있습니다

public class UrlShortenerSkypnetModule : AbstractSkypenetModule 

이 추상 모듈에 대한 유일한 중요한 것은 내 UrlShortner은과 같이 스카이프에 대한 이벤트를 등록 할 수 있다는 것입니다 같은 부모 추상 모듈과 그 이름에 따라 그 인스턴스에 다른 IUrlShortenerProvider를 삽입하십시오. 이것에 더하여, 이것에 대해 올바른 방법이 있습니까?

public class TinyUrlProvider : IUrlShortenerProvider 
public class GoogleUrlProvider : IUrlShortenerProvider 

모두 구현 인스턴스화 및 구현이 예를 들어 "구글"또는 내 UrlShortnerskypenetModule가 정의 할 수 있습니다 "티니 URL", 트리거 단어에 일치하는 경우는 것을 해당 인스턴스가 요청을 처리 있도록

?

은 지금까지 나는 다음과 같습니다 내 UrlShortenerModule에 대한 NinjectModul 전자를 가지고 있지만, 그것은 완전히 잘못이다, 그러나 희망 내가 본 어떤 종류의 내가

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", ""); 
    } 
} 

을 acomplish 노력하고있어 이해를 제공합니다 Spring.config에서 객체를 정의하고 abstract = "true"를 가지고이를 부모 객체로 선언 한 다음 동일한 부모 추상 객체를 갖는 두 개의 객체를 가질 수있는 Spring.NET 구성과 비슷한 동작을합니다. 나는 이것이 내가 무엇을하고 있는지를 믿는다. 그러나 나는 용기와 의존성 주입을 설정하는 데까지 이르지 못했다.

답변

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", ""); 
+1

내가 솔루션이 너무 복잡하고 당신이하는 간단한 룩업 사전, 를 사용하지만, Ninject에를 사용하여 스스로 할 수 있다고 생각 처음에는 패트릭 갈 좋은 솔루션을 더 쉽게 테스트하고 종속성 클리너를 관리하는 데 도움이됩니다. –

+0

조사해 주셔서 감사합니다! –

관련 문제