I know there are a few similar question out there regarding this issue with structure map, but my issue seems to not be resolvable with the solutions they needed. I must state I have used this same setup many times, but cannot see why this code is causing issues.
Here are all of the classes I think that are needed for help with troubleshooting my code.
ControllerConvention.cs
public class ControllerConvention : IRegistrationConvention
{
public void ScanTypes(TypeSet types, Registry registry)
{
foreach (Type type in types.AllTypes())
{
if (type.CanBeCastTo(typeof(Controller)) && !type.IsAbstract)
{
registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
}
}
}
}
IoC.cs
public static class IoC
{
public static IContainer Container { get; set; }
static IoC()
{
Container = new Container();
}
}
StandardRegistry.cs
public class StandardRegistry : Registry
{
public StandardRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.Assembly("PotSmart.Service");
scan.Assembly("PotSmart.Data");
scan.WithDefaultConventions();
});
}
}
StructureMapDependencyResolver.cs
public class StructureMapDependencyResolver : IDependencyResolver
{
private readonly Func<IContainer> _factory;
public StructureMapDependencyResolver(Func<IContainer> factory)
{
_factory = factory;
}
public object GetService(Type serviceType)
{
if (serviceType == null)
{
return null;
}
var factory = _factory();
return serviceType.IsAbstract || serviceType.IsInterface
? factory.TryGetInstance(serviceType)
: factory.GetInstance(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _factory().GetAllInstances(serviceType).Cast<object>();
}
}
Global.asax
public IContainer Container
{
get
{
return (IContainer)HttpContext.Current.Items["_Container"];
}
set
{
HttpContext.Current.Items["_Container"] = value;
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
DependencyResolver.SetResolver(new StructureMapDependencyResolver(() => Container ?? IoC.Container));
IoC.Container.Configure(cfg =>
{
cfg.AddRegistry(new StandardRegistry());
cfg.AddRegistry(new ControllerRegistry());
});
}
Here are parts of my data and entities classes:
RepositoryBase.cs
public class RepositoryBase
{
private readonly PotSmartEntityModel1 _dataContext;
protected IDbFactory DbFactory { get; private set; }
protected PotSmartEntityModel1 DbContext
{
get
{
return _dataContext ?? DbFactory.Init();
}
}
protected RepositoryBase(IDbFactory dbFactory)
{
DbFactory = dbFactory;
var adapter = (IObjectContextAdapter)this;
var objectContext = adapter.ObjectContext;
// objectContext.CommandTimeout = 120; // value in seconds
}
}
public abstract class RepositoryBase<T> where T : class
{
private readonly PotSmartEntityModel1 _dataContext;
private readonly IDbSet<T> _dbSet;
protected IDbFactory DbFactory { get; private set; }
protected PotSmartEntityModel1 DbContext
{
get
{
return _dataContext ?? DbFactory.Init();
}
}
protected RepositoryBase(IDbFactory dbFactory)
{
DbFactory = dbFactory;
_dbSet = DbContext.Set<T>();
}
public virtual void Add(T entity)
{
_dbSet.Add(entity);
}
public virtual void Update(T entity)
{
_dbSet.Attach(entity);
DbContext.Entry(entity).State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
_dbSet.Remove(entity);
}
public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = _dbSet.Where<T>(where);
foreach (T obj in objects)
{
_dbSet.Remove(obj);
}
}
public virtual T GetById(int id)
{
return _dbSet.Find(id);
}
public virtual T GetById(string id)
{
return _dbSet.Find(id);
}
public virtual IEnumerable<T> GetAll()
{
return _dbSet.ToList();
}
public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where).ToList();
}
public T Get(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where).SingleOrDefault();
}
public virtual IQueryable<T> Query()
{
return _dbSet;
}
public virtual IQueryable<T> Query(Expression<Func<T, bool>> where)
{
return _dbSet.Where(where);
}
public virtual ObjectQuery<U> CreateQuery<U>(string query, ObjectParameter[] parameters)
{
return CastAsObjectContext().CreateQuery<U>(query, parameters);
}
public virtual ObjectQuery<U> CreateQuery<U>(string query)
{
return CreateQuery<U>(query, new ObjectParameter[0] { });
}
public virtual ObjectQuery<DbDataRecord> CreateQuery(string query, ObjectParameter[] parameters)
{
return CreateQuery<DbDataRecord>(query, parameters);
}
public virtual ObjectQuery<DbDataRecord> CreateQuery(string query)
{
return CreateQuery<DbDataRecord>(query);
}
private ObjectContext CastAsObjectContext()
{
var oContext = (DbContext as IObjectContextAdapter).ObjectContext;
return oContext;
}
}
DBFactory.cs
class DbFactory : Disposable, IDbFactory
{
private PotSmartEntityModel1 _dbContext;
public PotSmartEntityModel1 Init()
{
return _dbContext ?? (_dbContext = new PotSmartEntityModel1());
}
protected override void DisposeCore()
{
if (_dbContext != null)
{
_dbContext.Dispose();
}
}
}
IDBFactory.cs
public interface IDbFactory : IDisposable
{
PotSmartEntityModel1 Init();
}
IRepository.cs
public interface IRepository
{
}
public interface IRepository<T> where T : class
{
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(Expression<Func<T, bool>> where);
T GetById(int id);
T GetById(string id);
IEnumerable<T> GetAll();
IEnumerable<T> GetMany(Expression<Func<T, bool>> where);
IQueryable<T> Query();
IQueryable<T> Query(Expression<Func<T, bool>> where);
ObjectQuery<U> CreateQuery<U>(string query, ObjectParameter[] parameters);
ObjectQuery<U> CreateQuery<U>(string query);
ObjectQuery<DbDataRecord> CreateQuery(string query, ObjectParameter[] parameters);
ObjectQuery<DbDataRecord> CreateQuery(string query);
}
Now, sorry for so much code but that way I get all the answer out there that some in the community may ask. The issue is on my controller, I use no default constructor and do the dependency injection like the following code show:
MarkerController.cs
public class MarkerController : Controller
{
private readonly IMarkerService _markerService;
public MarkerController(IMarkerService markerService)
{
_markerService = markerService;
}
// GET: Markers
public ActionResult Index()
{
return View();
}
}
When I run the code I keep getting the following error, and have tried anything I could think of.
StructureMap.StructureMapConfigurationException: 'No default Instance is registered and cannot be automatically determined for type 'PotSmart.Data.Interfaces.IDbFactory'
I know StructureMap does not always have the clearest error messages, but I feel this meant my Entity model was not being initialized at run time for some reason.It fails during "factory.GetInstance(serviceType)". Has anyone had this error, or does anyone see what I am obviously overlooking in the code sets I have above that would cause this issue? Thanks a million as always in advance.