Pro Asp.Net MVC3 - the Apress book by Freeman and Sanderson
From "Listing 7开发者_如何学运维-7 Adding an Action Method" on Page 165 of the book
when I add "return View(repository.Products);" I get Error: the property or indexer 'SportsStore.Domain.Abstract.IProductRepository.Products' cannot be used in this context because the get accessor is inaccessible. And then when I try to run -- I get "Inconsistent accessibility: property type 'System.Linq.IQueryable' is less accessible than property'SportsStore.Domain.Abstract.IProductRepository.Products'
I am just trying to get to the point in the first section of Chapter 7, where the action method relies on a mock implementation of the repository interface, which generates some simple test data. Here's my code
NinjectControllerFactory.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Ninject;
namespace WebUI.Infrastructure
{
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()
{
// put additional bindings here
// Mock implementation of the IProductRepository Interface
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(mock => m.Products).Returns(new List<Product> {
new Product { Name = "Football", Price = 25 },
new Product { Name = "Surf board", Price = 179 },
new Product { Name = "Running shoes", Price = 95 }}.AsQueryable());
ninjectKernel.Bind<IProductRepository>().ToConstant(mock.Object);
}
}
}
Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System
.Web.Routing;
using WebUI.Infrastructure;
namespace WebUI
{
// 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 = "Product", action = "List", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
}
}
Product.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SportsStore.Domain.Entities
{
class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
}
IProductRepository.cs
using System.Linq;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract
{
public interface IProductRepository
{
IQueryable<Product> Products { get; }
}
}
ProuctController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
namespace WebUI.Controllers
{
public class ProductController : Controller
{
//
// GET: /Product/
private IProductRepository repository;
public ProductController(IProductRepository productRepository){
repository = productRepository;
}
public ViewResult List() {
return View(repository.Products);
}
}
}
List.cshtml
@model IEnumerable<SportsStore.Domain.Entities.Product>
@{
ViewBag.Title = "Products";
}
@foreach (var p in Model)
{
<div class= "item">
<h3>@p.Name</h3>
@p.Description
<h4>@p.Price.ToString("c")</h4>
</div>
}
Assemblyinfo.cs
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Domain")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Domain")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
IProductRepository.cs
using System.Linq;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Abstract
{
public interface IProductRepository
{
IQueryable<Product> Products { get; }
}
}
Make your Product class public.
public class Product {
blah blah blah
}
I don't have the book but let's look at what it says - the get accessor is inaccessible. So is the property public or private? Without the code I'm guessing, but it sure sounds like you're trying to access a property that isn't explicitly marked public
.
Access modifiers. Somewhere not specified or private.
IProductRepository must be implemented from IDisposable. Like ObjectContext
They are in different projects. So, in the current project add a reference to the SportsStore.Domain project(right click on the project->add reference->projects tab). You will get visibility.
Good book. It's working for me so far .... Are you missing the concrete class "EFProductRepository"?
using System.Linq;
using SportsStore.Domain.Abstract;
using SportsStore.Domain.Entities;
namespace SportsStore.Domain.Concrete
{
public class EFProductRepository : IProductRepository
{
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products
{
get { return context.Products; }
}
}
}
I had the same compile issue. I fixed it by setting the Product class as Public.
精彩评论