2012-12-15 15 views
5

मैं एएसपी.नेट एमवीसी 4 के साथ निनजेक्ट का उपयोग कर रहा हूं। मैं रिपोजिटरी का उपयोग कर रहा हूं और नियंत्रकों में से किसी एक को भंडार में पास करने के लिए कन्स्ट्रक्टर इंजेक्शन करना चाहता हूं।निदान: कन्स्ट्रक्टर पैरामीटर

public class AzureTableRepository<T> : IRepository<T> where T : TableServiceEntity 
{ 
    private readonly string _tableName; 
    private readonly TableServiceContext _dataContext; 

    private CloudStorageAccount _storageAccount; 
    private CloudTableClient _tableClient; 

    public AzureTableRepository(string tableName) 
    { 
     // Create an instance of a Windows Azure Storage account 
     _storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString); 

     _tableClient = _storageAccount.CreateCloudTableClient(); 
     _tableClient.CreateTableIfNotExist(tableName); 
     _dataContext = _tableClient.GetDataServiceContext(); 
     _tableName = tableName; 
    } 

नोट TableName पैरामीटर की जरूरत है क्योंकि मैं एक सामान्य तालिका भंडार उपयोग कर रहा था करने के लिए डेटा लागू करने के लिए:

public interface IRepository<T> where T : TableServiceEntity 
{ 
    void Add(T item); 
    void Delete(T item); 
    void Update(T item); 
    IEnumerable<T> Find(params Specification<T>[] specifications); 
    IEnumerable<T> RetrieveAll(); 
    void SaveChanges(); 
} 

नीचे AzureTableStorageRepositoryIRepository<T> के एक कार्यान्वयन है:

यह मेरा भंडार इंटरफेस है Azure।

और अंततः मेरे पास निम्न नियंत्रक है।

public class CategoriesController : ApiController 
{ 
    static IRepository<Category> _repository; 

    public CategoriesController(IRepository<Category> repository) 
    { 
     if (repository == null) 
     { 
      throw new ArgumentNullException("repository"); 
     } 

     _repository = repository; 
    } 

अब मैं नियंत्रक में एक भंडार इंजेक्ट करना चाहता हूं। तो मैं एक मॉड्यूल बाइंडिंग शामिल बनाया है:

/// <summary> 
/// Ninject module to handle dependency injection of repositories 
/// </summary> 
public class RepositoryNinjectModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IRepository<Category>>().To<AzureTableRepository<Category>>(); 
    } 
} 

मॉड्यूल की लोडिंग में किया जाता है NinjectWebCommon.cs

/// <summary> 
    /// Creates the kernel that will manage your application. 
    /// </summary> 
    /// <returns>The created kernel.</returns> 
    private static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

     RegisterServices(kernel); 
     return kernel; 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     // Load the module that contains the binding 
     kernel.Load(new RepositoryNinjectModule()); 

     // Set resolver needed to use Ninject with MVC4 Web API 
     GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel); 
    } 

DependencyResolver बनाया गया था क्योंकि Ninject के DependencyResolverSystem.Web.Mvc.IDependencyResolver लागू करता है और इस को सौंपा नहीं किया जा सकता है WebApi एप्लिकेशन के ।

तो यह सब जगह के साथ, निंजा भाग वास्तव में नियंत्रक में सही प्रकार इंजेक्शन कर रहा है लेकिन निनजेक्ट AzureTableRepository के निर्माता में तालिका नाम पैरामीटर इंजेक्ट नहीं कर सकता है।

मैं इस मामले में ऐसा कैसे कर पाऊंगा? मैंने पैरामीटर का उपयोग कैसे कर सकता है यह देखने के लिए मैंने कई लेख और निपुण दस्तावेज़ीकरण से परामर्श लिया है, लेकिन मुझे लगता है कि यह काम नहीं कर रहा है।

किसी भी मदद की सराहना की जाएगी।

उत्तर

10

मैं WithConstructorArgument() विधि की तरह उपयोग करना चाहते हैं ...

Bind<IRepository<Category>>().To<AzureTableRepository<Category>>() 
    .WithConstructorArgument("tableName", "categories"); 

भंडार डिजाइन के बाकी शायद एक और सवाल है। IMHO यह एक टेबल बनाने के लिए एक बड़ी संख्या नहीं है या एक ctor में कोई भारी उठाने लगता है।

+0

मुझे लगता है कि मैं रचनात्मक से ... निर्माण को हटा दूंगा क्योंकि यह वास्तव में सीटीआर में प्रारंभिकरण करने के लिए एक अच्छा अभ्यास नहीं है। Thx! –

0

इस बीच मैं चालकों के साथ चाल चलने और करने के लिए चारों ओर खेल रहा हूं और ऐसा लगता है कि यह काम करता है।

अगर यह अच्छा विचार है या अगर यह overkill है, लेकिन यहाँ मैं क्या किया है मैं नहीं जानता: मैं एक सामान्य प्रदाता वर्ग बनाया है:

public abstract class NinjectProvider<T> : IProvider 
{ 
    public virtual Type Type { get; set; } 
    protected abstract T CreateInstance(IContext context); 

    public object Create(IContext context) 
    { 
     throw new NotImplementedException(); 
    } 

    object IProvider.Create(IContext context) 
    { 
     throw new NotImplementedException(); 
    } 

    Type IProvider.Type 
    { 
     get { throw new NotImplementedException(); } 
    } 
} 

और फिर मैं उस में एक कार्यान्वित AzureTableRepositoryProvider। (टी एकाधिक इकाई प्रकार के लिए एक ही भंडार होने का समर्थन करने के।) इस प्रदाता मैं सही तालिका नाम में भंडार के साथ काम करने के लिए पारित कर सकते हैं का उपयोग करके

public class AzureTableRepositoryProvider<T> : Provider<AzureTableRepository<T>> where T : TableServiceEntity 
{ 
    protected override AzureTableRepository<T> CreateInstance(IContext context) 
    { 
     string tableName = ""; 

     if (typeof(T).Name == typeof(Category).Name) 
     { 
      // TODO Get the table names from a resource 
      tableName = "categories"; 
     } 
     // Here other types will be addedd as needed 

     AzureTableRepository<T> azureTableRepository = new AzureTableRepository<T>(tableName); 

     return azureTableRepository; 
    } 
} 

। लेकिन मेरे लिए, दो प्रश्न रहते हैं:

  1. क्या यह अच्छा अभ्यास है या क्या हम चीजों को अधिक सरल बना सकते हैं?
  2. निनजेकप्रोवाइडर कक्षा में मेरे पास दो कार्यान्वित अपवाद मामले नहीं हैं। मैं इन्हें कैसे हल कर सकता हूं? मैंने निम्नलिखित लिंक से नमूना कोड का उपयोग किया लेकिन यह काम नहीं करता है क्योंकि प्रदाता अमूर्त है और कोड के पास विधि बनाने के लिए कोई शरीर नहीं है ...enter link description here
संबंधित मुद्दे