RadioButtonList exception - asp.net

After I upgraded to the beta, I'm having trouble with Html.RadioButtonList. Can someone show me what I'm doing wrong?
The code:
<% Html.RadioButtonList(
"voter" + voter.Id,
new SelectList(new[]{"yes","no","abstain"}, "yes")).Each(x => Response.Write(x)); %>
And the exception I get:
[ArgumentNullException: Value cannot be null.
Parameter name: value]
System.Web.Mvc.Html.InputExtensions.RadioButton(HtmlHelper htmlHelper, String name, Object value, Boolean isChecked, IDictionary`2 htmlAttributes) +214
Microsoft.Web.Mvc.<>c__DisplayClass1.<RadioButtonListInternal>b__0(ListItem item) in c:\dd\Cicero\src\Mvc\main\src\MvcFutures\Mvc\RadioExtensions.cs:86
System.Linq.WhereSelectListIterator`2.MoveNext() +107
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +259
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +81
Microsoft.Web.Mvc.RadioListExtensions.RadioButtonListInternal(HtmlHelper htmlHelper, String name, SelectList selectList, Boolean usedViewData, IDictionary`2 htmlAttributes) in c:\dd\Cicero\src\Mvc\main\src\MvcFutures\Mvc\RadioExtensions.cs:88
Microsoft.Web.Mvc.RadioListExtensions.RadioButtonList(HtmlHelper htmlHelper, String name, SelectList selectList) in c:\dd\Cicero\src\Mvc\main\src\MvcFutures\Mvc\RadioExtensions.cs:29
Many thanks in advance!
Rob

It looks like you may have found a bug in the MVC framework. The other overloads of RadioButtonList seem to work just fine, but that particular overload barfs.
From looking at Reflector (and using the stack trace) I looks like things go awry at this line:
return selectList.GetListItems().Select<ListItem, string>(delegate (ListItem item) {
return htmlHelper.RadioButton(name, item.Value, item.Selected, htmlAttributes);
}).ToArray<string>();
In the Microsoft.Web.Mvc.RadioListExtensions.RadioButtonListInternal method. I assume this code worked fine in Preview 5?

Related

Integrating FluentValidation with ASP.NET Core 3.1 and view components

I just updated my application to .NET Core 3.1 and fluent validation to the latest version (8.6.2) and I am getting the following error when rendering view components, which have input fields.
System.NullReferenceException: Object reference not set to an instance of an object.
at FluentValidation.AspNetCore.ValidatorDescriptorCache.GetCachedDescriptor(ClientValidatorProviderContext context, IHttpContextAccessor httpContextAccessor) in
/home/jskinner/code/FluentValidation/src/FluentValidation.AspNetCore/ValidatorDescriptorCache.cs:line 45
at FluentValidation.AspNetCore.FluentValidationClientModelValidatorProvider.CreateValidators(ClientValidatorProviderContext context) in \/home\/jskinner\/code\/FluentValidation\/src\/FluentValidation.AspNetCore\/FluentValidationClientModelValidatorProvider.cs:line 73
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.CompositeClientModelValidatorProvider.CreateValidators(ClientValidatorProviderContext context)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientValidatorCache.GetValidators(ModelMetadata metadata, IClientModelValidatorProvider validatorProvider)
at Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultValidationHtmlAttributeProvider.AddValidationAttributes(ViewContext viewContext, ModelExplorer modelExplorer, IDictionary`2 attributes)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ValidationHtmlAttributeProvider.AddAndTrackValidationAttributes(ViewContext viewContext, ModelExplorer modelExplorer, String expression, IDictionary`2 attributes)
at Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.AddValidationAttributes(ViewContext viewContext, TagBuilder tagBuilder, ModelExplorer modelExplorer, String expression)
at Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateInput(ViewContext viewContext, InputType inputType, ModelExplorer modelExplorer, String expression, Object value, Boolean useViewData, Boolean isChecked, Boolean setId, Boolean isExplicitValue, String format, IDictionary`2 htmlAttributes)
at Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateTextBox(ViewContext viewContext, ModelExplorer modelExplorer, String expression, Object value, String format, Object htmlAttributes)
at Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.GenerateHidden(ModelExplorer modelExplorer, IDictionary`2 htmlAttributes) at Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper.Process(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.RunAsync(TagHelperExecutionContext executionContext)
at AspNetCore.Views_Waardecheck_SubscribeToEmail_SubscribeToEmail_Unsubscribed.<ExecuteAsync>b__11_0() in
The issue is that on a view component, the HttpContext of the IHttpContextAccessor instance is null, and therefore giving a null reference exception when fluent validation tries to insert the validators into the pipeline. And I do have services.AddHttpContextAccessor(); in the Startup.
This is one of the affected views. If I remove the asp-for tag helper in the input field then it works. But that's not really a solution.
<div data-subscribe-to-email class="waardecheck-subscribe-to-email waardecheck-subscribe-to-email--unsubscribed fd-bg-light-3 fd-padding-horizontal fd-padding-vertical-s fd-justify-content-between fd-border-light-2 fd-border-horizontal-remove fd-border-bottom-remove">
<p class="fd-margin-none fd-margin-bottom-xs">#WaardecheckResources.EnableUpdatesDescription</p>
<form asp-action="UpdateEmailPreferences">
<input asp-for="SelectedEmailFrequency" value="#Model.SelectedEmailFrequency" type="hidden">
<button type="submit" class="fd-btn fd-btn--primary-alt fd-btn--block"><span class="icon-alert-white"></span> Enable</button>
</form>
</div>
Has anybody encountered the same issue, or do you have any idea on how can I work around this?

Stop ASP.NET MVC from calling all getters in a model class

If you define the following two properties on your model class this will crash with a NullReferenceException during model binding:
public Customer Customer { get; private set; } //set in the action method
public bool Name => Customer.Name;
This is because Customer is still null during model binding and ASP.NET MVC calls the getter for Name.
The stack is:
System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component) +525
System.Web.Mvc.ModelMetadata.get_Model() +34
System.Web.Mvc.DataAnnotationsModelValidator.Validate(Object container) +151
System.Web.Mvc.<Validate>d__1.MoveNext() +387
System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +163
System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +83
System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +1754
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +460
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +137
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +982
System.Web.Mvc.<>c__DisplayClass22.<BeginExecuteCore>b__1e() +39
System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action) +21
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +44
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +65
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +399
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +137
From the stack it looks like model validation is querying all getters. I'm not using model validation.
How can I deal with this situation? Can I make ASP.NET MVC not call all getters without any (apparent) reason?
So the Model Binder new's up an instance of your Model, then is probably doing reflection over the model's properties to look for named matches with the values in the FormCollection. What's happening is that the Customer prop is null when that dangerous Name prop is called, thus the NullRef.
The order by which .NET is checking those properties might not be actually random, but your code will be much improved by just treating it as such. Calling a method/prop directly on a Class that's nullable by default is a terrible idea, unless you check it for null. You have two options here, either (1) redesign your Model class so that the Constructor initializes the "Customer" property, or (b) add a null-check in that "Name" method.
Here's the easiest approach to just null-checking it when you grab it:
public bool Name => Customer?.Name ?? false;
This does not solve the underlying issue, which is that you have a Model that has nullable props chained together. Don't worry about your Model's constructor messing up your model binding. The Model Binder will (1) initialize your model class, then (2) try to hydrate it. So initializing the Customer class/prop in your Model's constructor won't impact any mapping of UI fields to say that Customer's fields.
The DefaultModelBinder in MVC version 5.2.3 does validation in addition to binding, and there is no way to shut it off completely. Other SO posts mention turning off the implicit required attribute for value types with the following line of code in your Global.asax.cs, Application_Start() method...
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
See: https://stackoverflow.com/a/2224651 (which references a forum with an answer directly from the asp.net team).
Given your stack trace, that might fix your immediate problem. However, that probably won't be enough due to the DefaultModelBinder calling the getters even outside of its validation code for no stated reason (the source code makes no comment as to why it does that).
To solve the problem on my projects, where I use calculated properties all the time similar to your example, I implemented a custom model binder based on the original DefaultModelBinder source code that does not call any getters.
See a more detailed explanation and my full solution here: https://stackoverflow.com/a/54431404/10987278.

File does not exist when searching custom partial view paths

I'm getting a strange issue on our MVC app. We are inheriting the RazorViewEngine to create a custom view engine, to facilitate custom logic in the arrangement of views.
We have a list of potential view paths:
PartialViewLocationFormats = new[]
{
"~/Views/Partial/Shared/Base/$thing/{0}.$otherthing.cshtml",
"~/Views/Partial/Shared/Base/$thing/{0}.cshtml",
"~/Views/Partial/Shared/Base/{0}.$otherthing.cshtml",
"~/Views/Partial/Shared/Base/{0}.cshtml"
};
Then we override the FileExists method, like:
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
return base.FileExists(controllerContext, this.ParsePath(controllerContext, virtualPath));
}
ParsePath method looks like:
private string ParsePath(ControllerContext controllerContext, string virtualPath)
{
string newPath = virtualPath;
BaseController controller = controllerContext.Controller as BaseController;
if (controller != null)
{
if (controller.Model != null)
{
if (!string.IsNullOrEmpty(controller.Model.Thing))
{
newPath = newPath.Replace("$thing", controller.Model.Thing);
}
if (!string.IsNullOrEmpty(controller.Model.OtherThing))
{
newPath = newPath.Replace("$otherthing", controller.Model.OtherThing);
}
}
}
return newPath;
}
This works fine locally, but after publishing to a Win 2012, IIS8 box, I'm seeing the following error:
The file '/Views/Partial/Shared/Base/Footer.blar.cshtml' does not exist.
TargetSite: System.Web.Compilation.BuildResult GetVPathBuildResultInternal(System.Web.VirtualPath, Boolean, Boolean, Boolean, Boolean, Boolean)
StackTrace: at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) yadda yadda yadda
'/Views/Partial/Shared/Base/Footer.cshtml' does exist, why does it throw the exception?
My hunch is the code is fine and its a issue with IIS - I've checked that the sites are running integrated mode etc...
Any ideas?
This is happening because of an optimization MVC has when you have the application set to debug="false". Once I set debug="true", This error went away for me.

No parameterless constructor object defined

I know that this is a duplicate question but i can't find answer to my error.
I'm trying to show a list of my rooms saved in database but i get next error:
Server Error in '/' Application.
No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
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: No parameterless constructor defined for this object.]
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) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67
[InvalidOperationException: An error occurred when trying to create a controller of type 'HotelProjectFinal.Controllers.RoomController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +232
System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8969412
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
But i have a constructor withou a parameter:
namespace HotelProjectFinal.Controllers
{
public class RoomController : Controller
{
private IRoomRepository repository;
public RoomController(IRoomRepository roomRepository)
{
repository = roomRepository;
}
public ViewResult List()
{
return View(repository.Rooms);
}
}
}
My view is :
#model IEnumerable<HotelProjectFinal.Models.Room>
#{
ViewBag.Title = "List";
}
#foreach (var p in Model)
{
<div class="item">
<h3>#p.Room_number</h3>
#p.Room_Type
<h4>#p.Room_Type.Price.ToString("c")</h4>
</div>
}
I am using ninject:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext,
Type controllerType)
{
return controllerType == null
? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings()
{
ninjectKernel.Bind<IRoomRepository>().To<EFRoomRepository>();
}
}
}
You've got a controller factory, but the fact that the stacktrace says nothing about Ninject suggests you have forgotten to tell MVC about it.
You could fix that by adding a line to tell it that.
However the recommended practice is to hook Ninject in by adding a NuGet reference to Ninject.MVC3. There are docs about it on the associated Ninject MVC3 wiki.
Please try changing your constructors to the following:
public RoomController() { } // You were missing this parameterless constructor
[Inject]
public RoomController(IRoomRepository roomRepository)
{
repository = roomRepository;
}
Ninject is looking for a parameterless constructor because you haven't specified [Inject] above constructor that you wish to use for dependency injection. This has confused "Ninject" and caused an exception to be thrown.
The primary DI pattern is Constructor Injection. When activating an instance of a type Ninject will choose one of the type’s constructors to use by applying the following rules in order:-
If a constructor has an [Inject] attribute, it is used (but if you apply the attribute to more than one, Ninject will throw a NotSupportedException at runtime upon detection).
If no constructors have an [Inject] attribute, Ninject will select the one with the most parameters that Ninject understands how to resolve.
If no constructors are defined, Ninject will select the default parameterless constructor (assuming there is one).
More information can be found here:
https://github.com/ninject/ninject/wiki/Injection-Patterns
As pointed out by Ruben, [Inject] attribute pollutes the controller with external concerns.
This ties your code to a specific container. (Although Ninject does permits the customization of the specific attribute to look for, the point remains – you’re polluting an interface with external concerns.)
Your actual problem probably relies in a missing reference to Ninject.MVC3
Even though IRoomRepository could be null, that doesn't make it a parameterless constructor. At first glace, it looks like your IoC isn't wired up correctly for IRoomRepository. With no IoC, or misconfigured IoC, the controller activator looks for a parameterless constructor for your controllers.
// This is a parameterless constructor.
public RoomController()
{ }
// This is not a parameterless constructor.
public RoomController(IRoomRepository roomRepository)
{
repository = roomRepository;
}
Edit, Are you using Ninject.Mvc and your base MvcHttpApplication is implementing NinjectHttpApplication?

ASP.NET MVC2 Error: No parameterless constructor defined for this object

Edit: This is fixed -- See Solution below
Solution: First I incorrectly had my node defined in /shared/web.config instead of the web.config in the root of the WebUI project. I also had not correctly defined my connection string within web.config. I have pasted the proper web.config sections below:
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
<!--more sectiongroup and sections redacted for brevity -->
</configSections>
<castle>
<components>
<component id="ProdsRepository" service="DomainModel.Abstract.IProductsRepository, DomainModel" type="DomainModel.Concrete.SqlProductsRepository, DomainModel">
<parameters>
<connectionString>Data Source=.\SQLExpress;Initial Catalog=SportsStore; Integrated Security=SSPI</connectionString>
</parameters>
</component>
</components>
</castle>
I also had to adjust the method body of WindsorControllerFactory.cs (IoC Container) to return null for invalid requests like so:
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
return null;
else
return (IController)container.Resolve(controllerType);
}
End of Solution
I'm following the book Pro ASP.NET MVC2 by Sanderson. I've implemented the IoC container and gotten the web.config straightened out. When I attempt to run my application I get the error "No parameterless constructor defined for this object"
After some searching I found this exact issue on SO here. The solution is to create the constructor with no parameters but I'm having an issue doing this. I've pasted the code from ProductsController.cs below
namespace WebUI.Controllers
{
public class ProductsController : Controller
{
private IProductsRepository productsRepository;
public ProductsController(IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
public ViewResult List()
{
return View(productsRepository.Products.ToList());
}
}
}
Above the public ProductsController that has parameters I tried doing:
public ProductsRepository() : this(new productsRepository())
{
}
I'm unclear about exactly what needs to go after the "new". IProductsRepository doesn't seem to work and neither does what I have written. I have pasted the stack trace below:
Stack Trace:
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86
System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230
System.Activator.CreateInstance(Type type, Boolean nonPublic) +67
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
[InvalidOperationException: An error occurred when trying to create a controller of type 'WebUI.Controllers.ProductsController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +190
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +68
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +118
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +46
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +63
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +13
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8682818
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Any help would be greatly appreciated.
Edit: Posting WindsorControllerFactory.cs code:
namespace WebUI
{
public class WindsorControllerFactory : DefaultControllerFactory
{
WindsorContainer container;
// The contructor:
// 1. Sets up a new IoC container
// 2. Registers all components specified in web.config
// 3. Registers all controller types as components
public WindsorControllerFactory()
{
// Instantiate a container, taking config from web.config
container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
// Also register all the controller types as transient
var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (Type t in controllerTypes)
container.AddComponentLifeStyle(t.FullName, t, Castle.Core.LifestyleType.Transient);
}
// Constructs the controller instance needed to service each request
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (IController)container.Resolve(controllerType);
}
}
}
Edit2: Pertinent Web.config nodes:
<configSections>
<section name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
Castle.Windsor" />
</configSections>
<castle>
<components>
<component id="ProdsRepository"
service="DomainModel.Abstract.IproductsRepository, DomainModel"
type="DomainModel.Concrete.SqlProductsRepository, DomainModel"></component>
<parameters>
</parameters>
</components>
</castle>
You need to configure a custom controller factory in order to wire up your DI framework inside Application_Start method in global.asax. So for example if you are using Unity as DI framework you could:
ControllerBuilder.Current.SetControllerFactory(
typeof(UnityControllerFactory)
);
Check out this blog post for more information.
you can make use of setter based injection
public class ProductsController : Controller
{
private IProductsRepository productsRepository;
public ProductsController()
{
}
public ViewResult List()
{
return View(productsRepository.Products.ToList());
}
public IProductsRepository MyRepository
{
get
{
return productsRepository;
}
set
{
productsRepository = value;
}
}
}
here , you need to manually set the MyRepository.
but best would be , if you register your repository to a container and beliving that you are using Unity framework , so you can do it by IUnityContainer.RegisterType() method

Resources