Сначала попробуйте StructureMap и MVC3 через NuGet.

Я пытаюсь понять, как настроить StructureMap для ASP.NET MVC3. Я уже использую NuGet и замечаю, что он создает папку App_Start с файлом cs с именем StructuremapMVC, поэтому я проверяю его и замечаю, что это тот же код, но упрощенный это будет написано вручную в разделе App_Start, размещенном на Global.asax...

Это мой код из класса IoC

public static class IoC
    {
        public static IContainer Initialize()
        {
            ObjectFactory.Initialize(x =>
                        {
                            x.Scan(scan =>
                                    {
                                        scan.TheCallingAssembly();
                                        scan.WithDefaultConventions();
                                        scan.AddAllTypesOf<IController>();
                                    });
                            x.For<OpcionDB>().Use(() => new DatabaseFactory().Get());
                        });
            return ObjectFactory.Container;
        }
    }

Мой вопрос: почему я получаю исключение, когда я ввожу IoC в свои контроллеры следующим образом (я использую этот шаблон: Entity Framework 4 CTP 4/CTP 5 Общий шаблон репозитория и возможность модульного тестирования):

        private readonly IAsambleaRepository _aRep;
        private readonly IUnitOfWork _uOw;

        public AsambleaController(IAsambleaRepository aRep, IUnitOfWork uOw)
        {
            _aRep = aRep;
            this._uOw = uOw;
        }

        public ActionResult List(string period)
        {
            var rs = _aRep.ByPeriodo(period).ToList<Asamblea>();

            return View();
        }

Исключение показало:

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

person Jonathan Escobedo    schedule 16.03.2011    source источник


Ответы (5)


Вы получаете эту ошибку, потому что вы не настроили StructureMap для разрешения зависимостей, необходимых для построения AsambleaController, поэтому он пытается найти конструктор без параметров, которого нет.

Итак, что вам нужно сделать, это настроить StructureMap для IAsambleaRepository и IUnitOfWork.

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

person Charlino    schedule 16.03.2011

Для обработки параметров в конструкторе контроллера необходимо настроить преобразователь зависимостей.

Проверьте следующий пост о том, как связать StructureMap с ASP.NET MVC3:

http://stevesmithblog.com/blog/how-do-i-use-structuremap-with-asp-net-mvc-3/

http://codebetter.com/jeremymiller/2011/01/23/if-you-are-using-structuremap-with-mvc3-please-read-this/

person codeprogression    schedule 16.03.2011

Если вы следовали сообщению в репозитории, вы захотите добавить эти конфигурации в свой файл IoC.cs:

x.For<IUnitOfWork>().HttpContextScoped().Use<UnitOfWork>();
x.For<IDatabaseFacroey>().HttpContextScoped().Use<DatabaseFactory>();
x.For<IAsambleaRepository >().HttpContextScoped().Use<AsambleaRepository>();

Вызов: scan.TheCallingAssembly(); будет смотреть только на проект MVC. Если у вас есть свои службы и репозитории в другом проекте в вашем решении, вам нужно будет добавить его следующим образом:

scan.Assembly("Your.Assembly");
person Paul    schedule 16.03.2011

Установка NuGet для StructureMap.MVC3 устанавливает файл с именем SmDependencyResolver.cs в папку DependencyResolution. Вы заметите, что в методе GetService есть try...catch, который просто возвращает null, если возникает исключение. Это может скрыть сведения об исключении, так что вместо этого вы увидите сообщение об ошибке «нет конструктора без параметров».

Чтобы получить больше информации об исходном исключении, вы можете добавить что-то в это предложение catch, чтобы выдать детали исходного исключения, например Debug.WriteLine здесь:

    public object GetService(Type serviceType)
    {
        if (serviceType == null) return null;
        try
        {
            return serviceType.IsAbstract || serviceType.IsInterface
                     ? _container.TryGetInstance(serviceType)
                     : _container.GetInstance(serviceType);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
            return null;
        }
    }

Это может помочь вам отследить источник проблемы.

person Richard    schedule 22.03.2012
comment
За все годы использования StructureMap я никогда не замечал этого, думаю, я собираюсь разорвать этот пробный блок. Я не думаю, что когда-либо хочу, чтобы StructureMap не пузырился. - person Chris Marisic; 31.07.2012

Запустите в отладке, вы, вероятно, получите ошибку разрешения StructureMap IOC.

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

person Chris Marisic    schedule 05.04.2011