Nano Hash - криптовалюты, майнинг, программирование

Создание экземпляра класса с внедренным конструктором в C#

Мне было интересно, можно ли создать объект класса, у которого есть конструктор с инъекцией другого класса.

Класс, который я хочу создать:

using ClearBlog.IRepository;
using ClearBlog.Models;

namespace ClearBlog.Areas.Admin.Classes
{
    public class AdminArticleTags
    {
        private readonly IGenericRepository<ArticleTag> _db = null;

        public AdminArticleTags(IGenericRepository<ArticleTag> db)
        {
            _db = db;
        }

        public int InsertNew(int article, int tag)
        {
            // do smt here
        }
    }
}

Я хочу использовать метод InsertNew вышеуказанного класса в другом классе, например:

using System.Linq;
using System.Web.Mvc;
using ClearBlog.Models;
using ClearBlog.Helpers;
using ClearBlog.IRepository;
using ClearBlog.Areas.Admin.Classes;

namespace ClearBlog.Areas.Admin.Controllers
{
    public class Someclass : Controller
    {
        private readonly IGenericRepository<Tag> _db = null;

        public Someclass(IGenericRepository<Tag> db)
        {
            _db = db;
        }

        public ActionResult Index()
        {
            AdminArticleTags at = new AdminArticleTags();
            at.InsertNew(10, 15);
        }
     }
 }

Сейчас это невозможно из-за того, что конструктор ожидает IGenericRepository.

Это вообще возможно?

Если нет, то какой способ посоветуете? Имейте в виду тот факт, что мне нужно использовать IGenericRepository, который является интерфейсом, используемым Ninject для привязки к реализации.

изменить:

то, что я пытаюсь сделать, очень просто. Я просто хочу создать объект AdminArticleTags и получить доступ к его методу внутри Someclass. даже если я создаю конструктор без параметров для AdminArticlesTags, он выдает ошибки, потому что он не собирается вводить IGenericRepository для этого объекта. (из-за конструктора)

Как мне создать объект AdminArticlesTags и использовать его методы??

изменить2:

здесь я делаю привязки Ninject:

using Ninject;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using ClearBlog.IRepository;
using ClearBlog.Repository;
using AutoMapper;

namespace ClearBlog.Infrastructure
{
    public class NinjectDependencyResolver : IDependencyResolver
    {
        private IKernel kernel;
        public NinjectDependencyResolver(IKernel kernelParam)
        {
            kernel = kernelParam;
            AddBindings();
        }
        public object GetService(Type serviceType)
        {
            return kernel.TryGet(serviceType);
        }
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return kernel.GetAll(serviceType);
        }
        private void AddBindings()
        {
            kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>));
            kernel.Rebind<IMappingEngine>().ToMethod(context => Mapper.Engine);
        }
    }
}
15.11.2015

  • Ваш пример не имеет особого смысла. Вы создаете экземпляр того же класса, внутри которого работаете, который также наследует контроллер? 16.11.2015
  • @YuvalItzchakov Сейчас исправлю. это опечатка. 16.11.2015
  • Вы хотите внедрить существующий экземпляр IGenericRepository? Используйте DependencyResolver.Current.GetService<IGenericRepository>(); и передайте его в конструктор. 16.11.2015
  • У @James Someclass есть собственная версия IGenericRepository другого типа. это не сработает для AdminArticlesTags 16.11.2015
  • @ VSG24, вам нужен новый экземпляр AdminArticleTags каждый раз, когда вызывается действие Index? 16.11.2015
  • @ VSG24, вы упомянули, что используете NInject. Можете ли вы показать, как? Я спрашиваю об этом, потому что для этого есть много способов. 16.11.2015
  • @YacoubMassad Думаю, это не имеет большого значения. а может да. 16.11.2015
  • @YacoubMassad внес правку. 16.11.2015

Ответы:


1

Используйте внедрение конструктора.

Если вам не нужно каждый раз получать новый экземпляр AdminArticleTags, просто введите AdminArticleTags в контроллер следующим образом:

public class Someclass : Controller
{
    private readonly AdminArticleTags m_AdminArticleTags;

    public Someclass(AdminArticleTags aat)
    {
        m_AdminArticleTags = aat;
    }

    public ActionResult Index()
    {
       m_AdminArticleTags.InsertNew(15, 42);
    }
}

Поскольку вы используете Ninject, он сможет создать контроллер и передать правильную зависимость.

Если вам требуется новый экземпляр каждый раз внутри действия Index, вам нужна какая-то фабрика. Вы можете использовать класс Func следующим образом:

public class Someclass : Controller
{
    private readonly Func<AdminArticleTags> m_AdminArticleTagsFactory;

    public Someclass(Func<AdminArticleTags> factory)
    {
        m_AdminArticleTagsFactory = factory;
    }

    public ActionResult Index()
    {
       AdminArticleTags at = m_AdminArticleTagsFactory();
       at.InsertNew(15, 42);
    }
}

В этом случае вам нужно будет установить пакет nuget Ninject.Extensions.Factory. Это позволит поддерживать разрешение фабрик на основе Func. Взгляните на это.

Альтернативой фабрикам на основе Func являются фабричные интерфейсы. Взгляните на это.

16.11.2015
  • Это сработало. Ваши примеры также были очень полезны. Спасибо. 16.11.2015
  • @Yacoub Massad, зачем вам каждый раз новый экземпляр внутри Index? Чем это может вам помочь? Потому что внедрение зависимостей в том виде, в каком оно есть, делает работу. Я не понимаю, почему было бы полезно создавать экземпляры AdminArticleTags каждый раз с помощью Func? Хотел бы научиться. Большое спасибо 04.09.2019
  • @VAAA, я думаю, что в хорошо разработанных приложениях вам не нужно создавать экземпляры каждый раз, когда вам нужно вызвать зависимость. Но многие приложения плохо спроектированы, и вы можете работать с кодовой базой, в которой существующие классы спроектированы таким образом, что вам приходится создавать экземпляры. Это верно, например, когда созданная зависимость содержит состояние, которое в какой-то момент должно начинаться с нуля. 04.09.2019

  • 2
    1. да. вы можете вводить код, даже если класс имеет параметризованный конструктор. хотя это зависит от того, как и с какой техникой/структурой вы вводите.

    2. то, что вы делаете в примере, не является инъекцией. просто простой пример. кроме того, ваш код не будет компилироваться, потому что вы не определили пустой конструктор или конструктор по умолчанию.

    может быть, если вы дадите более подробную информацию о том, чего вы пытаетесь достичь, вам будет легче конкретно помочь.

    15.11.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..