简体   繁体   中英

Castle Windsor + ASP MVC 5 - System.MissingMethodException: Cannot create an instance of an interface

First of all, sorry for my english. I am trying to do something small in windsor + mvc. I read some tutorials, and look for any solution of my problem, but i haven't found any. Use:

  • VS 2013 Express
  • ASP MVC 5.2.2 (.net 4.5)
  • Castle.Windsor 3.3.0 for .NETFramework v4.5

I want to build a modular app (web + domain + db layer), but i still get error:

Exception Details: System.MissingMethodException: Cannot create an instance of an interface.

Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[MissingMethodException: Cannot create an instance of an interface.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +159
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +256
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +127
   System.Activator.CreateInstance(Type type) +11
   System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +275

[MissingMethodException: Cannot create an instance of an interface. Object type 'Dashboard.Web.Services.Interfaces.ITestApi'.]
   System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +370
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +151
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +454
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +153
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) +1449
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +150

..............

Main class or function of my app ( right now all in the same module/dll .web )

public class HomeController : Controller
{
    public ActionResult Home(ITestApi test)
    {
        var result = test.Test();

        return View();
    }
}

ITestApi Interface

namespace Dashboard.Web.Services.Interfaces
{
    public interface ITestApi
    {
        string Test();
    }
}

TestApi Class

namespace Dashboard.Web.Services.Implementation
{
    public class TestApi : ITestApi
    {
        public string Test()
        {
            return "test";
        }
    }
}

in Global.asax

 private static void BootstrapContainer() {
                Container = new WindsorContainer();
                Container.Install(FromAssembly.InThisApplication());            
                // Create the Controller Factory
                var castleControllerFactory = new WindsorControllerFactory(Container);
                // Add the Controller Factory into the MVC web request pipeline
                ControllerBuilder.Current.SetControllerFactory(castleControllerFactory);
            }

installer

public class WebInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Classes.FromThisAssembly()
                .BasedOn<IController>()
                .LifestyleTransient()
                );

            container.Register(
                Classes.FromThisAssembly()
                .BasedOn<ITestApi>()
                .LifestyleTransient()
                );
        }
    }

I have tried a few different method for register TestApi class, but the result is always the same.

container.Register(
                Classes.FromAssemblyInThisApplication()
                .InSameNamespaceAs(typeof(ITestApi))
                //.WithServiceDefaultInterfaces()
                .WithService.DefaultInterfaces()
                .LifestyleTransient()
                );

Could anyone help me ?

I am not sure, but i think you are just registering all Classes who are using ITestApi against their own name, but you never say what class should be used when CastleWindsor should inject a ITestApi

Replace your

     container.Register(
            Classes.FromThisAssembly()
            .BasedOn<ITestApi>()
            .LifestyleTransient()
            );

with the C# version of this (Sorry, having only a VB.NET snippet)

container.Register(Component.For(Of ITestApi).ImplementedBy(Of TestApi).LifestyleTransient())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM