Разрешение зависимостей с помощью CastleWindsor

Я новичок в замке Виндзор. Когда дело доходит до разрешения зависимостей, оно прекрасно работает в приложении.NET MVC. На данный момент я разрешаю зависимости в CONTROLLERS, используя инжекцию Constr utor (Eg1) или инъекцию свойства (2). Проблема в том, что когда я пытаюсь разрешить зависимость в другом классе (не в классе контроллера) с помощью внедрения свойства, это не разрешается автоматически (например, 3)

Например, 1 - РАЗРЕШЕНИЕ ОК!

public class HomeController : Controller
{
    private IUserRepo _userRepo;

    public HomeController(IUserRepo userRepo)
    {
       _userRepo = userRepo;
    }

    public ActionResult Show()
    {
        return View(userRepo.GetAllUsers());
    }

}

Например, 2 - РАЗРЕШЕНИЕ ОК!

public class HomeController : Controller
{
    public IUserRepo _userRepo {get;set;}

    public HomeController()
    {
    }

    public ActionResult Show()
    {
       return View(_userRepo.GetAllUsers());
    }
}

Например, 3 - НЕ РАЗРЕШАЕТСЯ!

public class ValidationRepository
{
   public IUserRepo _userRepo {get;set;}

   public bool ValidateUser()
   {
        //Here _userRepo is never resolved.
        // NB: I want property injection instead of constructor injection, is there any way?
   }
}

Спасибо

2 ответа

Вы не показываете достаточно кода, чтобы окончательно сказать, почему ваша зависимость не разрешается. Вы не показываете, как создаются экземпляры классов, что очень важно для понимания того, как / разрешаются ли зависимости.

Тем не менее, я могу сделать обоснованное предположение здесь:

Ваши контроллеры используют фабрику контроллеров, которая разрешает каждый контроллер через контейнер (Windsor). Ваш ValidationRepository создается другим способом, который не управляется контейнером (например, new ValidationRepository()). Чтобы разрешение зависимости работало, ValidationRepository должен принадлежать к той же цепочке зависимостей, что и ваши контроллеры - другими словами, это должна быть зависимость одного из контроллеров (или зависимость зависимости и, следовательно, часть зависимости). цепочка зависимостей).

Если вы действительно создаете экземпляр ValidationRepository вручную (используя new), контроллер не знает о классе и, следовательно, не может разрешить его зависимости. Попробуйте сделать ValidationRepository зависимостью конструктора от одного из ваших контроллеров и посмотрите, работает ли это.

Вы должны убедиться, что экземпляры IUserRepo и ValidationRepository зарегистрированы в вашем контейнере Windsor, прежде чем другие элементы в контейнере (например, ваши контроллеры) могут зависеть от них, и прежде чем они могут зависеть друг от друга. Например, что-то вроде:

container.Register(
            Component.For<IUserRepo>()
            .LifeStyle.Transient.
            .ImplementedBy<YourRealUserRepo>());

container.Register(
            Component.For<ValidationRepository>()
                .LifestyleTransient());

Учитывая то, что вы написали, похоже, что вы уже позаботились о первом шаге, поскольку ваши контроллеры с радостью подбирают экземпляры IUserRepo.

Как только ValidationRepository будет там, вы можете использовать либо инъекцию свойства, либо конструктор, и все это будет просто работать.

Однако обратите внимание, что это будет работать только в том случае, если вы получите свой экземпляр ValidationRepository из контейнера Castle Windsor. Выполнение "нового ValidationRepository()" создаст его экземпляр вне контейнера, и Castle Windsor не будет знать, как внедрить зависимости. В идеале ValidationRepository должен быть зависимостью от другого объекта в контейнере, как параметр свойства или конструктора зависимого объекта. Тогда Castle Windsor просто создаст для вас экземпляр по мере необходимости.

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

var validationRepository = Container.Resolve<ValidationRepository>();

Где "Контейнер" - это ссылка на Контейнер Castle Windsor, который вы, возможно, присвоили статическому свойству в некотором классе класса IoC Utility при настройке контейнера в первую очередь.

Тем не менее, это может быть примером Anti-pattern Service Locator, и его следует избегать. Вместо этого лучше всего позволить фабрике контроллеров следить за созданием контроллера как частью конвейера MVC, а затем иметь все другие необходимые зависимости, связанные с ним, либо в виде свойств, либо параметров конструктора. Например, контроллер имеет зависимость ValidationRepository, затем ValidationRepository имеет зависимость IUserRepo и т. Д.

Другие вопросы по тегам