I am creating a sample app with AngularJS, Asp.Net Web API 2, Generic Repository Pattern in data access Layer (I have IRepository and Repository added in the DAL Project) and I have UserContext class which uses CodeFirst Approach.
I have added StructureMap.WebAPI2 Nuget in my Web API Project. My IRepository code is
public interface IRepository<C,T>
{
IQueryable<T> GetAll();
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
T GetById(int id);
void Save();
}
My Repository class is as follows:
public class Repository<C, T> : IRepository<C, T> where T : class where C : DbContext,new()
{
private C _entities = new C();
public C Context
{
get { return _entities; }
set { _entities = value; }
}
protected DbSet<T> DbSet;
public Repository(DbContext dataContext)
{
DbSet = Context.Set<T>();
}
public void Add(T entity)
{
_entities.Set<T>().Add(entity);
Save();
}
public void Delete(T entity)
{
_entities.Set<T>().Remove(entity);
Save();
}
public void Edit(T entity)
{
_entities.Entry(entity).State = System.Data.Entity.EntityState.Modified;
Save();
}
public IQueryable<T> GetAll()
{
IQueryable<T> query = _entities.Set<T>();
return query;
}
public T GetById(int id)
{
return DbSet.Find(id);
}
public void Save()
{
_entities.SaveChanges();
}
}
In My Web API Project My controller has a parameter
public class UserAccountController : ApiController
{
private readonly IRepository<UserContext,UserAccount> _useraccount;
[DefaultConstructor]
public UserAccountController(IRepository<UserContext, UserAccount> useraccount)
{
_useraccount = useraccount;
}
[HttpPost]
public int AddUser(UserAccount useracct)
{
UserAccount user3 = new UserAccount() { Name = "Oza", Email = "[email protected]", Address = "Dover" };
_useraccount.Add(user3);
return user3.Id;
}
[HttpGet]
public IHttpActionResult GetUserByID(int id)
{
UserAccount useracc = _useraccount.GetById(id);
return Ok(useracc);
}
[HttpGet]
public List<UserAccount> GetUsersList()
{
return _useraccount.GetAll().ToList<UserAccount>();
}
[HttpPut]
public void ModifyUser(UserAccount useracc, int id)
{
if (useracc.Id == id)
{
_useraccount.Edit(useracc);
}
}
[HttpDelete]
public void DeleteUser(int id)
{
UserAccount useracc = _useraccount.GetById(id);
if (useracc != null)
{
_useraccount.Delete(useracc);
}
}
}
My WebAPI Config has following code
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
App_Start.StructuremapWebApi.Start();
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
MyDefaultRegistry.cs (which got added in DependencyResolution Folder after adding the nuget) has
public class DefaultRegistry : Registry { #region Constructors and Destructors
public DefaultRegistry() {
Scan(
scan => {
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.Assembly("EntityFramework");
scan.Assembly("EntityFramework.SqlServer");
scan.Assembly("DataAccessLayer");
scan.Assembly("DomainModels");
scan.Assembly("DataRepositories");
});
//For<IExample>().Use<Example>();
For<DataRepositories.IRepository<UserContext, UserAccount>>().Use<DataRepositories.Repository<UserContext, UserAccount>>();
}
Finally my Global.Asax I have added below lines of Code
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
IContainer container = DependencyResolution.IoC.Initialize();
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapWebApiDependencyResolver(container);
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Now when I try to run the application and access the service from my browser it throws the following error.
Unable to create a build plan for concrete type System.Data.Entity.DbContext
new DbContext(String nameOrConnectionString)
┗ String nameOrConnectionString = Required primitive dependency is not explicitly defined
1.) Attempting to create a BuildPlan for Instance of System.Data.Entity.DbContext -- System.Data.Entity.DbContext
2.) new Repository`2(*Default of DbContext*)
3.) Repository<UserContext, UserAccount>
4.) Instance of IRepository<UserContext, UserAccount> (Repository<UserContext, UserAccount>)
5.) new UserAccountController(*Default of IRepository<UserContext, UserAccount>*)
6.) NAPService.Controllers.UserAccountController
7.) Instance of NAPService.Controllers.UserAccountController
8.) Container.GetInstance(NAPService.Controllers.UserAccountController)