2016-06-15 25 views
1

私は、より高度な開発者が書いたこのコードがどのように機能しているかを理解しようとしています。私は完全に混乱しています。私は誰かが私がこのプロジェクトに存在するさまざまなクラスとインターフェースを理解できるように助けてくれることを願っていました。基本クラス、派生クラス、およびIクラス?

編集中のWebアプリケーションとは別に、クラスライブラリdllに外部クラスがあります。それをクラス外と呼んでみましょう。なぜこのクラスのコンストラクタが非常に多く、どのコンストラクタにデフォルトのWebRequestHandlerがあり、それ以外のコンストラクタだけが要求されていないのかということがわかりません。 Webアプリケーションでは、このクラスのインスタンスはWebRequestHandlerをnullにして初期化されます。これは、ここに...私が狂いそうですoutsideClassです:

public class outsideClass : webServiceInterface 
{ 
    private HttpClient _client = null; 
    private const int _TIMEOUT = 50; 
    private const string _assemblyName = "my.assembly.name"; 
    private const string _resourcesName = "my.assembly.name.Properties.Resources"; 
    private const string _certName = "client_cert_name"; 

    private static WebRequestHandler CreateDefaultMessageHandler() 
    { 
     // ProgressMessageHandler prog = new ProgressMessageHandler(); 
     //HttpClientHandler handler = new HttpClientHandler(); 

     WebRequestHandler handler = new WebRequestHandler(); 

     // The existing HttpClientHandler.SupportsProxy property indicates whether both the UseProxy property and the Proxy property are supported. 
     // This created an issue because some platforms(for example, Windows Phone) don’t allow you to configure a proxy explicitly. 
     // However, Windows Phone lets you control whether the machine wide proxy should be used. 
     // To model this behavior, we added the HttpClientHandler.SupportsUseProxy() extension method. 
     // For some platforms that don’t support both, such as Windows Phone, the SupportsProxy property will continue to return false, but the SupportsUseProxy() method will return true. 
     if (handler.SupportsProxy) // false on WinPhone 
     { 
      handler.Proxy = CrossWebProxy.SystemWebProxy; 
      handler.UseProxy = true; 
     } 

     // HttpClientHandler.SupportsAllowAutoRedirect(): The HttpClientHandler.SupportsRedirectConfiguration property had a similar issue: 
     // It controls whether both the AllowAutoRedirect and the MaxAutomaticRedirections properties are supported. 
     // Windows Phone doesn’t support specifying the maximum number of automatic redirections, but it does support redirection. 
     // For that reason, we added the HttpClientHandler.SupportsAllowAutoRedirect() extension method. 
     /* 
     if (handler.SupportsRedirectConfiguration)  // false on WinPhone 
     { 
      handler.MaxAutomaticRedirections = 5; 
     } */ 
     if (handler.SupportsRedirectConfiguration) 
     { 
      handler.AllowAutoRedirect = true; 
     } 

     X509Certificate2 certificate = getClientCertificate(); 
     handler.ClientCertificates.Add(certificate); 

     return handler; 
    } 

    private static X509Certificate2 getClientCertificate() 
    { 
     System.Reflection.Assembly myAssembly; 
     myAssembly = System.Reflection.Assembly.Load(_assemblyName); 
     ResourceManager myManager = new ResourceManager(_resourcesName, myAssembly); 

     byte[] cert_file_bytes; 
     cert_file_bytes = (byte[])myManager.GetObject(_certName); 

     //string[] names = myAssembly.GetManifestResourceNames(); 
     //using (Stream cert_file_stream = myAssembly.GetManifestResourceStream(names[0])) 
     //using (var streamReader = new MemoryStream()) 
     //{ 
     // cert_file_stream.CopyTo(streamReader); 
     // cert_file_bytes = streamReader.ToArray(); 
     //} 

     X509Certificate2 cert_file = new X509Certificate2(cert_file_bytes, "server"); 
     return cert_file; 
    } 

    public outsideClass(params DelegatingHandler[] handlers) : this(null, handlers) 
    { 
    } 

    public outsideClass(WebRequestHandler innerHandler, params DelegatingHandler[] handlers) : this("", "", innerHandler, handlers) 
    { 
    } 

    public outsideClass(string aUser, string aPass, params DelegatingHandler[] handlers) : this(aUser, aPass, null, null, handlers) 
    { 
    } 

    public outsideClass(string aUser, string aPass, Uri aBaseAddress, params DelegatingHandler[] handlers) : this(aUser, aPass, null, null, handlers) 
    { 
    } 

    public outsideClass(string aUser, string aPass, WebRequestHandler innerHandler, params DelegatingHandler[] handlers) : this(aUser, aPass, null, innerHandler, handlers) 
    { 
    } 

    public outsideClass(string aUser, string aPass, Uri aBaseAddress, WebRequestHandler innerHandler, params DelegatingHandler[] handlers) 
    { 
     if (innerHandler == null) 
     { 
      innerHandler = CreateDefaultMessageHandler(); 
     } 

     if (handlers != null) 
     { 
      DelegatingHandler excHandler = handlers.FirstOrDefault(t => t is WebServiceExceptionsHandler); 
      if (excHandler == null) 
      { 
       // Add the custom handler to the list 
       // So this Client will raise only exception of type WebServiceException/WebServiceOfflineException/WebServiceTimedOutException/WebServiceStatusException 
       excHandler = new WebServiceExceptionsHandler(); 
       IList<DelegatingHandler> list = handlers.ToList(); 
       list.Insert(0, excHandler); 
       handlers = list.ToArray(); 
      } 
     } 

     _client = HttpClientFactory.Create(innerHandler, handlers); 
     Timeout = TimeSpan.FromSeconds(_TIMEOUT); 
     SetCredentials(aUser, aPass); 

     BaseAddress = aBaseAddress; 
    } 

    protected long MaxResponseContentBufferSize 
    { 
     get { return _client.MaxResponseContentBufferSize; } 
     set { _client.MaxResponseContentBufferSize = value; } 
    } 

    protected HttpRequestHeaders DefaultRequestHeaders { get { return _client.DefaultRequestHeaders; } } 

    public Uri BaseAddress 
    { 
     get { return _client.BaseAddress; } 
     set { _client.BaseAddress = value; } 
    } 

    public TimeSpan Timeout 
    { 
     get { return _client.Timeout; } 
     set { _client.Timeout = value; } 
    } 

    public string Id { get; private set; } 
    public string Key { get; private set; } 

    /// <summary> 
    /// Set Basic Authentication Header 
    /// </summary> 
    public void SetCredentials(string aApplicationId, string aApplicationKey) 
    { 
     Id = aApplicationId; 
     Key = aApplicationKey; 
     _client.DefaultRequestHeaders.Authorization = null; 

     if (string.IsNullOrEmpty(Id) == true || 
      string.IsNullOrEmpty(Key) == true) 
     { 
      return; 
     } 

     _client.DefaultRequestHeaders.Authorization = 
      new AuthenticationHeaderValue("Basic", 
      Convert.ToBase64String(System.Text.UTF8Encoding.UTF8.GetBytes(string.Format("{0}:{1}", 
      this.Id, this.Key)))); 
    } 

    protected async Task<T> SendAndReadAsAsync<T>(HttpRequestMessage aRequest, MediaTypeFormatterCollection formatters, CancellationToken aCancellationToken = default(CancellationToken)) 
    { 
     HttpResponseMessage response = await _client.SendAsync(aRequest, aCancellationToken).ConfigureAwait(false); 
     return await response.Content.ReadAsAsync<T>(formatters).ConfigureAwait(false); 
    } 

    protected async Task<T> SendAndReadAsAsync<T>(HttpRequestMessage aRequest, CancellationToken aCancellationToken = default(CancellationToken)) 
    { 
     HttpResponseMessage response = await _client.SendAsync(aRequest, aCancellationToken).ConfigureAwait(false); 
     return await response.Content.ReadAsAsync<T>().ConfigureAwait(false); 
    } 

    protected async Task<string> SendAndReadAsStringAsync(HttpRequestMessage aRequest, CancellationToken aCancellationToken = default(CancellationToken)) 
    { 
     HttpResponseMessage response = await _client.SendAsync(aRequest, aCancellationToken).ConfigureAwait(false); 
     return await response.Content.ReadAsStringAsync().ConfigureAwait(false); 
    } 

    protected async Task<Stream> SendAndReadAsStreamAsync(HttpRequestMessage aRequest, HttpCompletionOption aCompletionOption = HttpCompletionOption.ResponseHeadersRead, CancellationToken aCancellationToken = default(CancellationToken)) 
    { 
     HttpResponseMessage response = await _client.SendAsync(aRequest, aCompletionOption, aCancellationToken).ConfigureAwait(false); 
     return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); 
    } 

    protected async Task<byte[]> SendAndReadAsByteArrayAsync(HttpRequestMessage aRequest, CancellationToken aCancellationToken = default(CancellationToken)) 
    { 
     HttpResponseMessage response = await _client.SendAsync(aRequest, aCancellationToken).ConfigureAwait(false); 
     return await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); 
    } 

    protected async Task<HttpResponseMessage> SendAsync(HttpRequestMessage aRequest, CancellationToken aCancellationToken = default(CancellationToken)) 
    { 
     HttpResponseMessage response = await _client.SendAsync(aRequest, aCancellationToken).ConfigureAwait(false); 
     return response; 
    } 
} 

webServiceInterface(なぜこれが必要とされていると目的は何ですか?):これは混乱されているコードがある

public interface webServiceInterface 
{ 
    Uri BaseAddress { get; set; } 
    TimeSpan Timeout { get; set; } 
    string Id { get; } 
    string Key { get; } 
    void SetCredentials(string aId, string aKey); 
} 

(なぜ?)地獄私の外に、Webアプリケーションで見つかった、IConnClientとConnClientクラスがあり、それらは次のように定義されています。最後に

public interface IConnClient : IClientWebService 
{ 
    Task UpdateSomethingAsync(Guid aCompanyId, Guid aUserId, Guid aAgronomistId, bool shareCN1, bool getRxMap, DateTime endDate, CancellationToken aCancelToken = default(CancellationToken)); 
    Task<IList<SomethingDto>> GetSomethingListAsync(Guid aCompanyId, CancellationToken aCancelToken = default(CancellationToken)); 
    Task DeleteSomethingAsync(Guid aCompanyId, Guid aAgronomistId, CancellationToken aCancelToken = default(CancellationToken)); 
    Task<IList<StuffDto>> GetStuffListAsync(Guid aCompanyId, CancellationToken aCancelToken = default(CancellationToken)); 
    Task<IList<StuffDto>> GetStuffListAsync(Guid aCompanyId, Guid aAgronomistId, CancellationToken aCancelToken = default(CancellationToken)); 
    Task<IList<StuffDto>> GetStuffListForThingsAsync(Guid aCompanyId, Guid aThingsId, CancellationToken aCancelToken = default(CancellationToken)); 
    Task<IList<ThingsDetailsDto>> GetThingsListAsync(Guid aCompanyId, CancellationToken aCancelToken = default(CancellationToken)); 
    Task<string> SendStuffListToThingsListAsync(Guid aCompanyId, Guid aUserId, IList<StuffDto> aStuffList, IList<Guid> aThingsList, CancellationToken aCancelToken = default(CancellationToken)); 

    // Task<bool> GetStuffStatusAsync(Guid aCompanyId, string aStuffId, CancellationToken aCancelToken = default(CancellationToken)); 
} 


public class ConnClient : outsideClass, IConnClient 
{ 
    private const string _SHARE_CN1 = "Share-CN1"; 
    private const string _GET_RXMAP = "Get-RxMap"; 

    private DateTime Epoch2DateTime(long epoch) 
    { 
     return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(epoch); 
    } 

    private long DateTime2Epoch(DateTime datetime) 
    { 
     return (long)datetime.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; 
    } 

    public ConnClient(Uri aBaseAddress, string apiKey, WebRequestHandler innerHandler = null, params DelegatingHandler[] handlers) 
     : base("", "", innerHandler, handlers) // DIP - IoC 
    { 
     DefaultRequestHeaders.Authorization = null; // TODO: Add authorization? 
     DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey); 
     BaseAddress = aBaseAddress; 
    } 

    public async Task UpdateSomethingAsync(Guid aCompanyId, Guid aUserId, Guid aAgronomistId, bool shareCN1, bool getRxMap, DateTime endDate, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(UpdateSomethingAsync) + " Company GUID is Empty"); 
     if (aUserId == Guid.Empty) 
      throw new ArgumentException(nameof(UpdateSomethingAsync) + " User GUID is Empty"); 
     List<string> permissions = new List<string>(); 
     if (shareCN1) 
     { 
      permissions.Add(_SHARE_CN1); 
     } 
     if (getRxMap) 
     { 
      permissions.Add(_GET_RXMAP); 
     } 
     UpdateSomethingRequestDto reqDto = new UpdateSomethingRequestDto(); 
     reqDto.Somethings = new Somethings(); 
     reqDto.Somethings.userId = aUserId; 
     reqDto.Somethings.thirdparty = aAgronomistId; 

     if (endDate.Year != 1) 
      reqDto.Somethings.endDate = DateTime2Epoch(endDate); 
     else 
      reqDto.Somethings.endDate = 0; 

     reqDto.Somethings.permissions = permissions; 

     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, "companies/" + aCompanyId + "/Somethings"); 

     JsonMediaTypeFormatter fmt = new JsonMediaTypeFormatter(); 
     request.Content = new ObjectContent(reqDto.GetType(), reqDto, fmt, "application/json"); 

     var res = await SendAndReadAsStringAsync(request, aCancelToken); 
    } 

    public async Task<IList<SomethingDto>> GetSomethingListAsync(Guid aCompanyId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(GetSomethingListAsync) + " Company GUID is Empty"); 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "companies/" + aCompanyId + "/Somethings"); 
     GetSomethingsResponseDto res = await SendAndReadAsAsync<GetSomethingsResponseDto>(request, aCancelToken); 
     return res?.Somethings; 
    } 

    public async Task DeleteSomethingAsync(Guid aCompanyId, Guid aAgronomistId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(DeleteSomethingAsync) + " Company GUID is Empty"); 
     if (aAgronomistId == Guid.Empty) 
      throw new ArgumentException(nameof(DeleteSomethingAsync) + " Agronomist GUID is Empty"); 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, "companies/" + aCompanyId + "/Somethings?thirdPartyId=" + aAgronomistId); 
     var res = await SendAndReadAsStringAsync(request, aCancelToken); 
    } 

    public async Task<IList<StuffDto>> GetStuffListAsync(Guid aCompanyId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(GetStuffListAsync) + " Company GUID is Empty"); 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "companies/" + aCompanyId + "/Stuffs"); 
     GetStuffsResponseDto res = await SendAndReadAsAsync<GetStuffsResponseDto>(request, aCancelToken); 
     return res?.Stuffs; 
    } 

    public async Task<IList<StuffDto>> GetStuffListAsync(Guid aCompanyId, Guid aAgronomistId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(GetStuffListAsync) + " Company GUID is Empty"); 
     if (aAgronomistId == Guid.Empty) 
      return await GetStuffListAsync(aCompanyId); 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "companies/" + aCompanyId + "/Stuffs?thirdPartyId=" + aAgronomistId); 
     GetStuffsResponseDto res = await SendAndReadAsAsync<GetStuffsResponseDto>(request, aCancelToken); 
     return res?.Stuffs; 
    } 

    public async Task<IList<ThingsDetailsDto>> GetThingsListAsync(Guid aCompanyId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(GetThingsListAsync) + " Company GUID is Empty"); 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "vehicles/?companyId=" + aCompanyId); 
     GetVehiclesResponseDto res = await SendAndReadAsAsync<GetVehiclesResponseDto>(request, aCancelToken); 
     return res?.vehicles; 
    } 

    private SendStuffsRequestDto CreateSendStuffDto(Guid aUserId, IList<StuffDto> aStuffList, IList<Guid> aVehicleList) 
    { 
     SendStuffsRequestDto res = new SendStuffsRequestDto(); 
     res.StuffData = new List<StuffDataDto>(); 
     res.userId = aUserId; 
     foreach (StuffDto prescr in aStuffList) 
     { 
      StuffDataDto data = new StuffDataDto(); 
      data.StuffID = prescr.StuffId; 
      data.vehicles = aVehicleList; 
      res.StuffData.Add(data); 
     } 
     return res; 
     /* 
     SendStuffsRequestDto res = new SendStuffsRequestDto(); 
     res.StuffData = new List<StuffDataDto>(); 
     res.userId = aUserId; 
     foreach (StuffDto prescr in aStuffList) 
     { 
      IList<Guid> prescrVehicleList = prescr.vehicleDetails.Select(l => l.vehicleId).ToList(); 
      IList<Guid> joinedList = aVehicleList.Where(c => prescrVehicleList.Contains(c)).ToList(); 
      if (joinedList == null || joinedList.Count == 0) 
       continue; 

      StuffDataDto data = new StuffDataDto(); 
      data.StuffID = prescr.StuffId; 
      data.vehicles = new List<Guid>(); 
      data.vehicles = joinedList; 
      res.StuffData.Add(data); 
     } 
     return res;*/ 
    } 

    public async Task<string> SendStuffListToThingsListAsync(Guid aCompanyId, Guid aUserId, IList<StuffDto> aStuffList, IList<Guid> aVehicleList, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(SendStuffListToThingsListAsync) + " Company GUID is Empty"); 
     if (aUserId == Guid.Empty) 
      throw new ArgumentException(nameof(SendStuffListToThingsListAsync) + " User GUID is Empty"); 

     SendStuffsRequestDto reqDto = CreateSendStuffDto(aUserId, aStuffList, aVehicleList); 
     if (reqDto.StuffData.Count == 0) 
      return ""; 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "companies/" + aCompanyId + "/Stuffs/send"); 

     JsonMediaTypeFormatter fmt = new JsonMediaTypeFormatter(); 
     request.Content = new ObjectContent(reqDto.GetType(), reqDto, fmt, "application/json"); 

     return await SendAndReadAsStringAsync(request, aCancelToken); 
    } 

    public async Task<IList<StuffDto>> GetStuffListForThingsAsync(Guid aCompanyId, Guid aVehicleId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     if (aCompanyId == Guid.Empty) 
      throw new ArgumentException(nameof(GetStuffListForThingsAsync) + " Company GUID is Empty"); 
     if (aVehicleId == Guid.Empty) 
      throw new ArgumentException(nameof(GetStuffListForThingsAsync) + " Vehicle GUID is Empty"); 

     IList<StuffDto> allPresc = await GetStuffListAsync(aCompanyId, aCancelToken); 
     List<StuffDto> res = new List<StuffDto>(); 
     foreach (StuffDto prescr in allPresc) 
     { 
      ThingsDetailsDto vehicle = prescr.vehicleDetails.FirstOrDefault(t => t.vehicleId == aVehicleId); 
      if (vehicle != null) 
      { 
       // Clones the Stuff... 
       ISerializationInterface serializer = new SerializationJson(); 
       string tmpString = serializer.Serialize(prescr); 
       StuffDto newPrescr = serializer.Deserialize<StuffDto>(tmpString); 
       // Remove all the vehicles 
       newPrescr.vehicleDetails.Clear(); 
       // Add the vehicle found 
       newPrescr.vehicleDetails.Add(vehicle); 
       res.Add(newPrescr); 
      } 
     } 
     return res; 
    } 

    /* 
    public Task<bool> GetStuffStatusAsync(Guid aCompanyId, string aStuffId, CancellationToken aCancelToken = default(CancellationToken)) 
    { 
     // This API has been marked as Optional on PostMan... 
     throw new NotImplementedException(); 
    } */ 
} 

、これは、それがコードで使用される方法です。

IConnClient connClient = ConnClientFactory.Create(); 
connClient.Timeout = TimeSpan.FromMinutes(4); 

//Then later in the code: 
connClient.GetStuffListAsync(companyGuid); 

私はおよそ非常に混乱しています部分がconnClientにこの部分である:

public ConnClient(Uri aBaseAddress, string apiKey, WebRequestHandler innerHandler = null, params DelegatingHandler[] handlers) 
     : base("", "", innerHandler, handlers) // DIP - IoC 

彼らは、innerHandler(WebRequestHandler)はデフォルトで初期化されていないコンストラクタを使用しているように見えますしたがって、それはどのようにWebサービス呼び出しを行うことができますか?誰もがこれらのクラスとインターフェイスのすべての間の接続を説明するのを助けることができますか?ここで何が起こっているのかを理解するのは非常に圧倒的です。

+0

私の意図ではない、少しネガティブに聞こえる危険性があります:あなたがそれを維持するか、あるいはそれを書き換えることができるように、これを必要なだけ学んでください。必ずしもそれを模倣するための例としてとらえてはいけません。それはちょっと複雑です。我々はすべてそれをやった。しかし、私はあなたがこれを投稿して以来、非常に経験豊富なプログラマーの多くがこれを見ていることを保証しています。 –

答えて

5

私はコントラクターチェーンの説明があなたの理解にかなり役立つと思います。

public outsideClass(params DelegatingHandler[] handlers) : this(null, handlers) { } 

これはoutsideClassの最初のコンストラクタです。本文にはボディはありませんが、この部分はさらに重要です:this(null, handlers)。コンストラクタのこの部分には、「まず、2つのパラメータをとり、余分なものを実行する他のコンストラクタを呼び出します。しかし、この場合、余分なものはありません。最終的にはすべてのあなたのロジックを持っているあなたの 'メイン' コンストラクタを呼び出し

public outsideClass(string aUser, string aPass, WebRequestHandler innerHandler, params DelegatingHandler[] handlers) : this(aUser, aPass, null, innerHandler, handlers) { } 

を呼び出し

ので

public outsideClass(params DelegatingHandler[] handlers) : this(null, handlers) { } 

通話

public outsideClass(WebRequestHandler innerHandler, params DelegatingHandler[] handlers) : this("", "", innerHandler, handlers) { } 

public outsideClass(string aUser, string aPass, Uri aBaseAddress, WebRequestHandler innerHandler, params DelegatingHandler[] handlers){ ... } 

あなたはこのようなあなたのコンストラクタを構築したい理由は、コードの重複を減らし、そしてあなたは、コンストラクタロジックを変更する必要がある場合、あなたは成功し、それらすべてを変更することを確認することです。

次に、ConnClientを見てみましょう。それのコンストラクタは、outsideClassとかなり類似し

public ConnClient(Uri aBaseAddress, string apiKey, WebRequestHandler innerHandler = null, params DelegatingHandler[] handlers) 
     : base("", "", innerHandler, handlers) // DIP - IoC 

のように見えますが、その代わりにthis(...)、それはbase("", "", innerHandler, handlers)を持っています。 basethisとよく似ていますが、SAMEクラスで別のコンストラクタを呼び出す代わりに、BASEクラスのコンストラクタを呼び出します。

だから、もう一度あなたの 'メイン' コンストラクタを呼び出し

public ConnClient(Uri aBaseAddress, string apiKey, WebRequestHandler innerHandler = null, params DelegatingHandler[] handlers) 
     : base("", "", innerHandler, handlers) // DIP - IoC 

通話

public outsideClass(string aUser, string aPass, WebRequestHandler innerHandler, params DelegatingHandler[] handlers) : this(aUser, aPass, null, innerHandler, handlers) { } 

public outsideClass(string aUser, string aPass, Uri aBaseAddress, WebRequestHandler innerHandler, params DelegatingHandler[] handlers){ ... } 

最後に、Interfacesについてのご質問にお答えします。コードでそれらを使用する理由はいくつかあります。最大のメリットのいくつかは、クラスの消費者を実際のクラスから切り離すことです。つまり、将来的に実装を変更する場合は、コード自体だけでなく、すべてのコンシューマを再処理する必要がなくなります。

データベースを操作するライブラリを作成している例を考えてみましょう。あなたはクラスMySqlDatabaseAdapaterを持っています。すべてのコードでMySqlDatabaseAdapterを使用していて、OracleDatabaseAdapterに変更する場合は、MySqlDatabaseAdapterを使用してすべてを変更する必要があります。しかし、MySqlDatabaseAdapterコードを手配してIDatabaseAdapterインターフェイスを実装し、すべての消費コードがIDatabaseAdapterを参照している場合は、OracleDatabaseAdapaterでコンシューマを置き換えることができます。この場合、IDatabaseAdapterが実装されています。

コードをテストする利点もあります。このようなネットワークアクティビティを実行するクラスがあり、このクラスを使用する単体テストコードにしたい場合、ユニットテストはネットワークアクティビティを実行します。良くない! しかし、インターフェイスアプローチを使用する場合は、テストしているコードにネットワークを襲うふりをする「偽の」IConnClientを与えるようにテストを設定できますが、実際はそうはしません。これにより、堅実で、予測可能で、速いテストを書くことができます。

希望すると便利です。

+0

これはあなたにとても感謝します:)))))!!!私は、フォローアップの質問をしたいと思っていました。下のconnClientによって使用されているコンストラクタに引数を追加する場合は、どうすれば外部クラスを変更できますか?コンストラクタのチェーンの上にあるすべてのコンストラクタに追加の引数を追加する必要がありますか? – KateMak

+1

@KateMakそれは本当にあなたが新しいパラメータで何をする必要があるかによって異なります。新しいパラメータは 'outsideClass'や' ConnClient'の動作に影響しますか? 'outsideClass'にそれが必要な場合は、それをチェーンに追加する必要があります。しかし、「ConnClient」だけが新しいパラメータを使用する必要がある場合は、それをチェーンに渡す必要はありません。実際はユースケースに依存しています。 –

+0

私は参照してください。すばらしい説明をありがとう! – KateMak

1

これは完全な答えではありませんが、書式設定されたコードをコメントに入れることはできません。

outsideClassinnerHandlerがコンストラクタにヌルであっても働くことができる理由です:

if (innerHandler == null) 
{ 
    innerHandler = CreateDefaultMessageHandler(); 
} 

また、この行の末尾にコメントが何か明らかにするかもしれません:

public ConnClient(Uri aBaseAddress, string apiKey, WebRequestHandler innerHandler = null, params DelegatingHandler[] handlers) 
    : base("", "", innerHandler, handlers) // DIP - IoC 

を私はと思われますDIP - IoCは、依存性注入コンテナ(「IoCコンテナ」とも呼ばれることもあります)への参照である可能性があります。つまり、Unity、Windsor、AutofacなどのDIコンテナを使用している可能性があります。プロジェクト内の参照を参照することがあります。もしそうなら、それはインターフェイスの特定の使用を説明するかもしれません。典型的なパターンは、

  • は、もしそのようにDIコンテナを構成
  • インタフェース
  • インターフェイス(ないクラス)に依存する他のクラスを作成し実装するクラスを定義するインターフェイスを定義

    • でありますクラスがインタフェースに依存する場合、コンテナはクラスのインスタンスを作成します。

    これは、依存性注入についての大きな説明ではありませんが、その推測が正しければ、これらのコンストラクタにどのような値が供給されるかを示すコードを見つけるのに役立ちます。

  • 関連する問題