Ninject:构造函数参数 [英] Ninject : Constructor parameter

查看:127
本文介绍了Ninject:构造函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Ninject与ASP.NET MVC一起4.我使用存储库和想要做的构造函数注入在仓库中传递给控制器​​之一。

这是我的仓库界面:

 公共接口IRepository< T>其中T:TableServiceEntity
{
    无效添加(T项目);
    无效删除(T项目);
    无效更新(T项目);
    IEnumerable的< T>查找(PARAMS规格及LT; T> []规格);
    IEnumerable的< T> RetrieveAll();
    无效的SaveChanges();
}

AzureTableStorageRepository 下面是 IRepository&LT的实现; T>

 公共类AzureTableRepository< T> :IRepository< T>其中T:TableServiceEntity
{
    私人只读字符串_tableName;
    私人只读TableServiceContext _dataContext;    私人CloudStorageAccount _storageAccount;
    私人CloudTableClient _tableClient;    公共AzureTableRepository(字符串tableName值)
    {
        //创建一个Windows Azure存储帐户的一个实例
        _storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings[\"StorageConnectionString\"].ConnectionString);        _tableClient = _storageAccount.CreateCloudTableClient();
        _tableClient.CreateTableIfNotExist(tableName值);
        _dataContext = _tableClient.GetDataServiceContext();
        _tableName = tableName值;
    }

请注意,因为我使用的是通用的表格资料库数据持久化到Azure的表名参数需要的。

最后,我有以下的控制器。

 公共类CategoriesController:ApiController
{
    静态IRepository<类别及GT; _repository;    公共CategoriesController(IRepository<分类和GT;库)
    {
        如果(库== NULL)
        {
            抛出新的ArgumentNullException(库);
        }        _repository =库;
    }

现在我想注入库到控制器。所以我创建了一个包含绑定的模块:

  ///<总结>
/// Ninject模块来处理库的依赖注入
///< /总结>
公共类RepositoryNinjectModule:NinjectModule
{
    公共覆盖无效负载()
    {
        绑定< IRepository<分类和GT;方式>()为<&AzureTableRepository LT;类别>>();
    }
}

模块的加载中完成的 NinjectWebCommon.cs

  ///<总结>
    ///创建将管理应用程序的内核。
    ///< /总结>
    ///<收益方式>创建的内核和LT; /回报>
    私有静态的iKernel CreateKernel()
    {
        VAR内核=新StandardKernel();
        kernel.Bind<&Func键LT;的iKernel>方式>()ToMethod(CTX =>()=>新建引导程序()内核。);
        kernel.Bind&所述; IHttpModule的方式>()到< HttpApplicationInitializationHttpModule>();        RegisterServices(内核);
        返回内核;
    }    ///<总结>
    ///装入模块或在这里注册您服务!
    ///< /总结>
    ///< PARAM NAME =内核方式>内核< /参数>
    私有静态无效RegisterServices(内核的iKernel)
    {
        //加载包含绑定的模块
        kernel.Load(新RepositoryNinjectModule());        //设置解析器需要使用Ninject与MVC4的Web API
        GlobalConfiguration.Configuration.DependencyResolver =新NinjectResolver(内核);
    }

DependencyResolver 的形成是因为Ninject的 DependencyResolver 工具 System.Web.Mvc.IDependencyResolver ,这不能的WebAPI应用被分配到 GlobalConfiguration.Configuration

所以,这一切到位,Ninject部分实际上是注入在控制器的权利类型,但Ninject不能在 AzureTableRepository 的构造函数注入表名参数。

如何将能够做到这一点在这种情况下?我咨询了很多文章和ninject文档,看我怎么可能用的参数,但我似乎无法得到它的工作。

任何帮助将是AP preciated。


解决方案

我会使用 WithConstructorArgument()方法一样...

<$p$p><$c$c>Bind<IRepository<Category>>().To<AzureTableRepository<Category>>()
    .WithConstructorArgument(tableName值,类别);

库设计的其余部分可能是另外一个问题。恕我直言,这似乎是一个很大的不,不创建一个表或做任何繁重的构造函数。

I am using Ninject together with ASP.NET MVC 4. I am using repositories and want to do constructor injection to pass in the repository to one of the controllers.

This is my Repository interface:

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

The AzureTableStorageRepository below is an implementation of IRepository<T>:

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

Note the tableName parameter needed because I was using a generic table repository to persist data to Azure.

And finally I have the following controller.

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

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

        _repository = repository;
    }

Now I want to inject a repository into the controller. So I have created a module that contains the bindings:

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

The loading of the module is done in the 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);
    } 

The DependencyResolver was created because Ninject's DependencyResolver implements System.Web.Mvc.IDependencyResolver and this cannot be assigned to GlobalConfiguration.Configuration of the WebApi Application.

So with all this in place, the Ninject part is actually injecting the right type in the Controller but Ninject cannot inject the tableName parameter in the constructor of AzureTableRepository.

How would I be able to do this in this case? I have consulted a lot of articles and the ninject documentation to see how I could use parameters, but I cannot seem to get it working.

Any help would be appreciated.

解决方案

I'd use the WithConstructorArgument() method like...

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

The rest of the repository design is probably another question. IMHO It seems like a big no no to create a table or do any heavy lifting in a ctor.

这篇关于Ninject:构造函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆