DevExpress с простым связыванием сетки Autofac - PullRequest
3 голосов
/ 23 ноября 2011

Я пытаюсь собрать реальный простой пример MVC DataBind. Я сравниваю Telerik против DevExpress Grid в MVC3. Одна из целей состояла в том, чтобы использовать Enitiy Framework и Autofac в подходе DDD, что делало его максимально приближенным к тому, как наши проекты в настоящее время и будут при использовании новых элементов управления. Создание честного теста.

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

{"Эта операция разрешения уже завершена. При регистрации компоненты, использующие лямбда-выражения, параметр IComponentContext 'c' для Лямбда не может быть сохранена. Вместо этого либо разрешите IComponentContext снова из 'c' или разрешите фабрику на основе Func <> для создания последующих компоненты от. "}

Я провел некоторое исследование по этому вопросу и уже вызывал функцию c.Resolve (), которая, по мнению многих, была исправлена, поэтому я не уверен, почему я продолжаю сталкиваться с этой проблемой, у Telerik не было проблем с той же точной настройкой.

Я почти уверен, что это не проблема DevExpress, и я думаю, что что-то не так с autofac. Однако, если именно так DevExpress и autofac работают вместе, это будет проблемой, так как мы сильно полагаемся на autofac, и я действительно не хотел бы делать что-то нелепое, чтобы заставить его работать, когда Telerik работает так легко из коробки.

Может кто-нибудь сказать мне, если я делаю что-то не так, и указать мне правильное направление, или сказать мне, если это проблема DevExpress и autofac, а не что-то, что можно легко исправить и требует обходного пути?

VIEW

@using System.Web.UI.WebControls
@model IEnumerable<Domain.Entities.FactResellerSale>
@{
    ViewBag.Title = "GridView";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>GridView</h2>

@Html.DevExpress().GridView(
        settings =>
            {
                settings.Name = "gvData";
                settings.Width = Unit.Percentage(100);

                settings.SettingsText.Title = "Fact Resllers Sale";
                settings.Settings.ShowTitlePanel = true;
                settings.Settings.ShowStatusBar = GridViewStatusBarMode.Visible;
                settings.SettingsPager.Mode = GridViewPagerMode.ShowAllRecords;
                settings.SettingsPager.AllButton.Text = "All";
                settings.SettingsPager.PageSize = 10;
            }
        ).Bind(Model).GetHtml()

Контроллер

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Domain.Entities;
using Domain.Repository;

namespace DevExpressMvcRazor.Controllers
{
    public class GridViewController : Controller
    {
        private readonly IAdventureRepository _repository;

        public GridViewController(IAdventureRepository repository)
        {
            _repository = repository;
        }

        //
        // GET: /GridView/

        public ActionResult GridView()
        {
            return View("GridView", GetFactResllerSales());
        }

        private IList<FactResellerSale> GetFactResllerSales()
        {
            return _repository.GetFactResllerSales().Take(10).ToList();
        }
    }
}

Global.asax

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Autofac;
using Autofac.Integration.Mvc;

namespace DevExpressMvcRazor
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            var builder = new ContainerBuilder();
            builder.RegisterModule<DevExpressModule>();
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }
}

DevExpressModule

using Autofac;
using Autofac.Integration.Mvc;
using Domain;
using Infrastructure;

namespace DevExpressMvcRazor
{
    public class DevExpressModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterControllers(typeof(MvcApplication).Assembly);

            builder.RegisterModule<InfrastructureModule>();
            builder.RegisterModule<DomainModule>();
            builder.RegisterModule<AutofacWebTypesModule>();
        }
    }
}

InfrastructureModule

    public class InfrastructureModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            builder.Register(c => new PropertyInjectedLazyLoadedObjectContextFactory(c.IsRegistered, c.Resolve))
                .As<IObjectContextFactory>()
                .InstancePerLifetimeScope();

            builder.Register(c => new UnitOfWork(c.Resolve<IObjectContextFactory>()))
                .As<ISession>()
                .As<IObjectContextProvider>()
                .InstancePerLifetimeScope();


            //Repositories
            builder.Register(c => new AdventureRepository(c.Resolve<IObjectContextProvider>()))
                .As<IAdventureRepository>()
                .InstancePerLifetimeScope();
        }
    }

Репозиторий

public class AdventureRepository : IAdventureRepository
{
    private readonly IObjectContextProvider _contextProvider ;

    public AdventureRepository(IObjectContextProvider contextProvider)
    {
        _contextProvider = contextProvider;
    }

    public IQueryable<FactResellerSale> GetFactResllerSales()
    {
        return _contextProvider.GetContext<TelerikVsDevExpressModelContext>().GetIQueryable<FactResellerSale>();
    }
}

Все остальное то же самое для Telerik, поэтому я просто опубликую View, который Telerik one работает без проблем. Telerik View

@model IEnumerable<Domain.Entities.FactResellerSale>              
@{
    ViewBag.Title = "GridView";
}

<h2>GridView</h2>


@(Html.Telerik().Grid(Model)
    .Name("Grid")
    .PrefixUrlParameters(false)
    .Columns(columns =>
    {
        columns.Bound(o => o.ProductKey).Width(50);
        columns.Bound(o => o.DimDate.FullDateAlternateKey);
        columns.Bound(o => o.DimReseller.ResellerName);
        columns.Bound(o => o.DimEmployee.FullName);
        columns.Bound(o => o.SalesOrderNumber);
    })
    .Groupable()
    .Pageable()
    .Sortable()
    .Filterable()
)

Я использую:

  • MVC 3
  • Autofac 2.5.2.830
  • DevExpress 11.1.8.0
  • Telerik 2011.3.1115.340

1 Ответ

4 голосов
/ 23 ноября 2011

Ваша проблема здесь:


 builder.Register(c => new PropertyInjectedLazyLoadedObjectContextFactory(c.IsRegistered, c.Resolve))
                .As<IObjectContextFactory>()
                .InstancePerLifetimeScope();

Чтобы добавить дескриптор к c (IComponentContext), вы должны сначала разрешить его. Измени свой код так:


 builder.Register(c => {
    var context = c.Resolve<IComponentContext>();
    return new PropertyInjectedLazyLoadedObjectContextFactory(context.IsRegistered, context.Resolve))
    }
  .As<IObjectContextFactory>()
  .InstancePerLifetimeScope();
...