В веб-формах я бы использовал внедрение зависимостей конструктора в своих моделях, как показано ниже:

[SitecoreType(AutoMap = true)]
public class Article
{
    private readonly ICommonService _commonService;

    public Article(ICommonService commonService)
    {
        _commonService = commonService;
    }

    [SitecoreId]
    private Guid Id { get; set; }

    public string Title { get; set; }

    [SitecoreIgnore]
    public string GetTestString
    {
        get { return _commonService.GetTestString(); }
    }
}

Идея здесь состоит в том, чтобы перенести логику в сервисы и сохранить слабую связь с DI. Таким образом, Glass предоставляет необработанные данные Sitecore, а сервисы помогают манипулировать этими данными или извлекать дополнительные данные для завершения модели.

Возможно ли иметь визуализацию представления со ссылкой на модель, которая разрешает DI, и модель готова к использованию?: @inherits Glass.Mapper.Sc.Web.Mvc.GlassView

В настоящее время, когда я пытаюсь это сделать, я получаю конструктор без параметров, определенный для этого объекта

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

Возможно ли, чтобы эта работа выполнялась в простом рендеринге представления, чтобы исключить создание представления контроллера для моделей, требующих логики в дополнение к простым данным Glass ORM?

В настоящее время опубликовано в группе Google Glass Mapper: https://groups.google.com/forum /#!topic/glasssitecoremapper/BJnfQGXR7S8

2
Jason Horne 20 Фев 2015 в 02:49

2 ответа

Для этого можно использовать конвейер ObjectConstruction. Вам нужно добавить новый класс, который реализует IObjectConstructionTask и разрешает ваш класс, используя ваш контейнер IoC, т.е.:

public class IoCResolvingTask : IObjectConstructionTask
{
    public virtual void Execute(ObjectConstructionArgs args)
    {
        // check that no other task has created an object and that this is a dynamic object
        if (args.Result != null || args.Configuration.Type.IsAssignableFrom(typeof(IDynamicMetaObjectProvider))) return;

        // create instance using your container
        var obj = Container.Resolve(args.Configuration.Type);

        // map properties from item to model
        args.Configuration.MapPropertiesToObject(obj, args.Service, args.AbstractTypeCreationContext);

        // set the new object as the returned result
        args.Result = obj;
    }
}

Затем вам нужно зарегистрировать свою задачу в Glass:

public static void CastleConfig(IWindsorContainer container){
    var config = new Config();

    container.Register(Component.For<IObjectConstructionTask>().ImplementedBy<IoCResolvingTask>().LifestylePerWebRequest());

    container.Install(new SitecoreInstaller(config));
}
2
Kevin Brechbühl 20 Фев 2015 в 09:56
Я добавил этот код в ваш первый фрагмент, так как у меня не было ссылки на контейнер. : закрытый только для чтения IWindsorContainer _container; public IoCResolvingTask (контейнер IWindsorContainer) { _container = container; } Должно ли это быть правильным? Затем я также добавил окончательный код, но все равно получаю ту же ошибку.
 – 
Jason Horne
22 Фев 2015 в 08:38
Вы также передали контейнер в регистрацию замка, например: container.Register(Component.For<IObjectConstructionTask>().ImplementedBy<IoCResolvingTask>().DependsOn(Dependency.OnValue<IWindsorContainer>(container).LifestylePerWebRequest());? С вашим кодом вы должны передать контейнер в качестве аргумента конструктора. Я не очень хорошо знаю замок и не знаю, работает ли фрагмент в этом комментарии, не проверял его.
 – 
Kevin Brechbühl
22 Фев 2015 в 12:31
Привет, я не регистрировался таким образом, однако я обновил сейчас, но все равно получаю ту же ошибку.
 – 
Jason Horne
23 Фев 2015 в 01:10
Зарегистрирован ли ваш IConmonService в контейнере, который вы передаете в конструкторе? Он зарегистрирован в том же контейнере, что и Glass? Или это другой каркас/контейнер? Что говорит отладчик? Вызывается задание на строительство? Вот руководство от Glass о том, как его использовать: glass.lu/en/Blog/ MixingInIoc.aspx
 – 
Kevin Brechbühl
23 Фев 2015 в 09:38
Спасибо за помощь, Кевин.
 – 
Jason Horne
29 Май 2015 в 11:26

Возможно ли иметь визуализацию представления со ссылкой на модель, которая разрешает DI, и модель готова к использованию?: @inherits Glass.Mapper.Sc.Web.Mvc.GlassView

Ответ: да, это можно сделать.

Внутри моделей DI разрешается автоматически. Из контроллеров и других областей я прибегал к использованию шаблона локатора служб: https://msdn .microsoft.com/en-us/library/ff648968.aspx

У меня возникла проблема с настройкой и настройкой. Вот код, который я реализовал для успешной работы.

GlassMapperCustom.cs

 public static void CastleConfig(IWindsorContainer container)
    {
        var config = new Config { UseWindsorContructor = true };

        container.Install(new SitecoreInstaller(config));
        container.Install(new ServiceInstaller());
    }  

Код установщика службы

public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Component.For<ICustomService>().ImplementedBy<CustomService>().LifestyleTransient(),            
            Component.For<SitecoreController>().ImplementedBy<SitecoreController>().LifestylePerWebRequest()
                .DependsOn(new { databaseName = Sitecore.Context.Database }));

        // Set up the servicelocator. We can use this in the code to get instances of services.
        ServiceLocator.SetLocatorProvider(() =>
                    new WindsorServiceLocator(container));
    }

Global.asax

   public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            "SiteName", // Route name 
            "SiteName/{controller}/{action}/{id}", // URL with parameters 
            new { controller = "Home", action = "Index", id = System.Web.Mvc.UrlParameter.Optional }); // Parameter defaults 
    }

    /// <summary>
    /// Registers the global filters.
    /// </summary>
    /// <param name="filters">Global filter collection.</param>
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    /// <summary>
    /// Will be called when the application first starts.
    /// </summary>
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }
0
Jason Horne 29 Май 2015 в 11:27