2011-09-23 7 views
6

क्या मेरे उत्पाद नियंत्रक को इंजेक्शन वाले लॉगर के लिए घोषित करने का कोई और तरीका है?किसी ऑब्जेक्ट के प्रकार का अनुमान लगाने के लिए और निर्माण के दौरान जेनेरिक पैरामीटर में उस प्रकार का उपयोग कैसे करें

public class ProductController : Controller 
{ 
    private readonly LoggingInterface.ILogger<ProductController> _logger; 
    private readonly IProductRepository _productRepository; 

    public ProductController(LoggingInterface.ILogger<ProductController> logger, IProductRepository productRepository) 
    { 
     _logger = logger; 
     _productRepository = productRepository; 
    } 
{ 

धन्यवाद, स्टीफन

+0

किस तरह से उचित है? –

+2

अनुमान को एक खुले जेनेरिक के उपयोग की आवश्यकता है। इस नमूने में कोई भी नहीं है – JaredPar

+0

मान लीजिए कि मैं शीर्षक संपादित कर सकता हूं और थोड़ा सा प्रश्न पूछ सकता हूं –

उत्तर

2

अनुमान को एक खुले जेनेरिक के उपयोग की आवश्यकता है। इस नमूने में कोई भी नहीं है

0

अगर मैं गलत नहीं हूँ, क्या तुम (इच्छुक तुम कर सकते हो) करने के लिए देख रहे हैं कुछ की तरह है:

class ProductController<T> : Controller where T : ProductController 
{ 
    ILogger<T> _logger; 
    ... etc 
} 

मुझे लगता है कि लगता है यदि आप अपने डिज़ाइन से थोड़ा पीछे खींचते हैं तो आप काफी लचीला इंटरफ़ेस प्राप्त कर सकते हैं। आपके पास तीन भाग हैं - एक नियंत्रक, एक लॉगर, और नियंत्रक और लॉगर का ऑब्जेक्ट, जिसे मैं डेटा ट्रांसफर ऑब्जेक्ट कहूंगा। इसलिए, आपके पास "उत्पाद का नियंत्रक" और "उत्पाद का लॉगर" है (जिसे आप वर्तमान में "उत्पाद के नियंत्रक के लॉगर" कहते हैं)।

मान लीजिए कि आप इस डीटीओ वस्तु संरचना है कि दो:

public class DataTransferBase { /*This is what both logger and controller operate on*/ } 

public class Product : DataTransferBase { } 

अब, नियंत्रकों के साथ ही विषय में लकड़हारा के बजाय, क्यों लकड़हारा और नियंत्रक दोनों DTOs के साथ खुद को चिंता की जरूरत नहीं? तो लकड़हारा की तरह है:

public interface ILogger 
{ 
    void Log(string message); 
} 

public interface ILogger<T> : ILogger where T : DataTransferBase 
{ 
    void Log(T item); 
} 

public class FileLogger<T> : ILogger<T> where T : DataTransferBase 
{ 
    public virtual void Log(T item) { /* Write item.ToString() to a file or something */ } 
    public void Log(string message) { /* Write the string to a file */ } 
} 

... और नियंत्रक की तरह है:

public interface IController<T> where T : DataTransferBase {} 

public class Controller<T> : IController<T> where T : DataTransferBase 
{ 
    /// <summary>Initializes a new instance of the ProductController class.</summary> 
    public Controller(ILogger<T> logger) 
    { 

    } 

    public virtual List<T> GetItems() 
    { 
     return new List<T>(); 
    } 
} 

क्या तुम यहाँ है अब एक लकड़हारा है कि किसी भी डीटीओ पर कार्यवाही करेंगे और एक नियंत्रक कि किसी भी डीटीओ संचालित हो सकता है , और वह नियंत्रक एक कन्स्ट्रक्टर पैरामीटर के रूप में लेने के लिए होता है, एक लॉगर जो उसी डीटीओ पर काम करेगा जो यह करता है। अब, आप अधिक विशिष्ट कार्यान्वयन अगर आप चाहते हैं हो सकता है:

public class ProductFileLogger : FileLogger<Product> 
{ 
    public override void Log(Product item) { /* Get all specific with item */} 
} 

और

public class ProductController : Controller<Product> 
{ 
    /// <summary> 
    /// Initializes a new instance of the ProductController class. 
    /// </summary> 
    public ProductController(ILogger<Product> productLogger) : base(productLogger) { } 

    public override List<Product> GetItems() 
    { 
     return new List<Product>(); 
    } 
} 

और, आप आप के रूप में के रूप में विशेष रूप से या आम तौर पर इन तार कर सकते हैं करें:

public class Client 
{ 
    private void DoSomething() 
    { 
     IController<Product> myController = new ProductController(new ProductFileLogger()); //If you want to be specific 
     IController<Product> myController2 = new Controller<Product>(new ProductFileLogger()); //If you want a generic controller and specific logger 
     IController<Product> myController3 = new Controller<Product>(new FileLogger<Product>()); //If you want to be as generic as possible 
    } 
} 

कृपया ध्यान दें, कि मैंने इसे फ्लाई पर फटकार दिया, इसलिए यह इष्टतम नहीं हो सकता है, लेकिन मैं सिर्फ सामान्य विचार व्यक्त करने की कोशिश कर रहा हूं। आप एक सामान्य प्रकार के (जहां तक ​​मुझे पता है) के साथ एक वर्ग घोषित नहीं कर सकते हैं, लेकिन आपके पास दो वर्गों (नियंत्रक और लॉगर) हो सकते हैं जो समान जेनेरिक प्रकार पर काम करते हैं। यही है, आईकंट्रोलर एक आईएलओगर का मालिक हो सकता है और जब आप आईसींट्रोलर को तुरंत चालू करते हैं, तो आप उसी लॉगर को उसी प्रकार पर संचालित करने के लिए मजबूर करते हैं।

+0

मुझे यह भी ध्यान रखना चाहिए कि यह सृजन के लिए एक सामान्य सार कारखाना या फैक्ट्री विधि रखने के लिए मैंने जो बनाया है उससे एक बहुत ही आसान कदम है। अगर यह मेरा कार्यान्वयन था, तो मैं वास्तव में उन चीजों को तार नहीं दूंगा जैसा मैंने "DoSomething()" में किया था - जो कि उदाहरण के लिए था। –

संबंधित मुद्दे

 संबंधित मुद्दे