Simple question I guess, but I've spent an hour trying to get a base class for my controllers to have a few services injected via property injection. The properties were scoped protected at first, but the objects kept coming back null, once I changed the scope to public it worked. Is there anyway to have the properties be protected and get the IoC to work?
Here is my setup.
public class BaseController : Controller
{
[Inject]
protected LoggingInterface.ILogger<BaseController> Logger { set; get; }
[Inject]
protected IRepository Repository { set; get; }
protected override void OnAuthorization(AuthorizationContext filterContext)
{
....
base.OnAuthorization(filterContext);
}
}
and the boot-strapper in the NinjectMVC3 App_Start
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(typeof(LoggingInterface.ILogger<>)).To(typeof(Log4NetLogger<>));
kernel.Bind<IRepository>().To<Repository>();
kernel.Bind<IUserService>().To<UserService>();
}
Thank you,
Stephen
You cannot inject into properties that do not have public setter. Both your Logger and Repository properties are protected so no way for Ninject to assign them a value. You will have to change their setter visibility if you want to achieve this. Or use constructor injection. While this would make perfect sense for the repository property which seems required it wouldn't make sense for the logger property. So I guess you will have to make it public.
Pretty sure the InjectNonPublic flag on the NinjectSettings allows you to configure it to do what you want - closest link I can find quickly
Whether it's going to be supported for any significant length of time, I don't know - injecting privates is just a bad idea (along with Property Injection and associated scoundrels :P)
Related
I have a custom dbcontext which name is Tracker-enabled DbContext (https://github.com/bilal-fazlani/tracker-enabled-dbcontext).I want to use it for audit log
And how can I implement EFRepository?
I implemented tracker-enabled-context but i cant solve how override sharp repo commit method.
public class HayEntities : TrackerContext
{
static HayEntities()
{
Database.SetInitializer<HayEntities>(null);
}
public HayEntities() : base(HayEntities)
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = true;
this.Configuration.ValidateOnSaveEnabled = false;
}
public DbSet<Dummy> Dummys{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DummyConfiguration());
} }
}
public class DummyRepository : ConfigurationBasedRepository<DE.Dummy, long>, IDummyRepository
{
private readonly IRepository<DE.Dummy, long> _servisHasarRepository;
public DummyRepository (HayEntities hayEntities, ICachingStrategy<DE.Dummy, long> cachingStrategy = null)
{this.CachingEnabled = false;
_dummyRepository = new EfRepository<DE.Dummy, long>(hayEntities, cachingStrategy);
}
public void UpdateOrCreate() {
//In this area how can override save/commit method
}
}
You will want to tell SharpRepository to use an IoC provider to inject the DbContext. This will take care of getting the proper DbContext for your EfRepository.
If you want to control things based on the configuration and have custom repositories so you can implement your own mehods like UpdateOrCreate() then you would inherit from ConfigurationBasedRepository as you have in the example.
There are more details on setting up IoC with SharpRepository here: http://fairwaytech.com/2013/02/sharprepository-configuration/ (look in the "Entity Framework and Sharing the DbContext" section)
First look on NuGet for SharpRepository.Ioc.* to find the specific IoC you are using. If you are using StructureMap then you would do something like this.
In your StructureMap configuration:
// Hybrid (once per thread or ASP.NET request if you’re in a web application)
For<DbContext>()
.HybridHttpOrThreadLocalScoped()
.Use<HayEntities>()
.Ctor<string>("connectionString").Is(entityConnectionString);
Then you need to tell SharpRepository to use StructureMap by calling this in your startup code:
RepositoryDependencyResolver.SetDependencyResolver(new StructureMapDependencyResolver(ObjectFactory.Container));
After doing these things, then if you use EfRepository then it will know to ask StructureMap for the DbContext.
Now in your example above where you are using ConfigurationBasedRepository, I would suggest setting the caching in the configuration file instead of in code since you are using the configuration to load the repository. Since IoC is handling the DbContext you don't need to do anyhing with that and you can focus on the custom method you want to write.
public class DummyRepository : ConfigurationBasedRepository<DE.Dummy, long>, IDummyRepository
{
public void UpdateOrCreate()
{
// You have access to the underlying IRepository<> which is going to be an EfRepository in your case assuming you did that in the config file
// here you can call Repository.Add(), or Reposiory.Find(), etc.
}
}
I using Ninject 3 in Repository pattern in mvc 3 (steven sanderson Scaffolder).
and in ninject i have the class "NinjectWebCommon" which in the "RegisterServices" method i resolved the dependencies and i think im ready to go.
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICityRepository>().To<CityRepository>();
kernel.Bind<IVillageRepository >().To<VillageRepository>();
}
i using my repositories in controllers using constructor injection and everything is fine.
public class CityController : Controller
{
private readonly ICityRepository cityRepository;
// If you are using Dependency Injection, you can delete the following constructor
//public CityController() : this(new CityRepository())
//{
//}
public CityController(ICityRepository cityRepository)
{
this.cityRepository = cityRepository;
}
// .........
}
but when i use this repositories in other classes like Model(Entity) classes using property injection or field injection the dependency doesn't resolved and i get null reference exception on my Property or field.
[MetadataType(typeof(CityMetadata))]
public partial class City : IValidatableObject
{
[Inject]
public IVillageRepository VillageRepo { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var village = VillageRepo.Find(5); // will throw null reference exception on "VillageRepo"
}
}
public partial class CityMetadata
{
[ScaffoldColumn(false)]
public int ID { get; set; }
[Required(ErrorMessage = MetadataErrorMessages.Required)]
[StringLength(50, ErrorMessage = MetadataErrorMessages.ExceedMaxLength)]
public string Name { get; set; }
}
i don't know why this happening. so whats the problem and how can i use the repositories in non-controller classes?
thanks in advance.
Your problem is, you're expecting magic. You inject an implementation for your repository, and then you expect that data objects created by that repository are injected with references of the creating repository.
First of all, that doesn't work like that. The implementation of the repository will call new() (or Activator.CreateInstance) on your entities, not ask for an instance from a Ninject Kernel or Factory. You could rewrite the repository (it'll get trickier if you're using EF there...) but it's probably not worth the hassle.
On the top of it all, you shouldn't be needing that at all. Entities shouldn't depend on repositories, imho not even their interfaces.
EDIT: now I see why you want to see a repo in your model. What I recommend is a static factory maybe.
public class Factories
{
public static readonly Instance = new Factories();
[Inject]
public Func<IVillageRepository> VillageRepo {get; set;}
}
Then call Kernel.Inject(Factories.Instance); from your Ninject initialization code (where you bind IVillageRepository). Then modify your validatable implementation to Factories.Instance.VillageRepo().Find(...);
In order to support lazy loading feature in EF, what is the best way to instantiate DbContext?
I know HttpContext's current item is good place to create DbContext via Application_BeginRequest method and Application_EndRequest method, but in some sample codes of MSDN and official asp.net mvc site, they just create DbContext in Controller's constructor and dispose it in controller's Dispose() method.
I think the both ways are not too different because all of those all implement session per request pattern.
I just want to make sure that my understanding is correct or not.
The Dispose() method in the controller isn't always reliable. By the same token, Session is probably not a good idea either. "Best" is probably subjective, but we've had the best success by using dependency injection (Castle Windsor) and following a Unit of Work Repository pattern.
Setup the unit of work along the following lines:
public class UnitOfWork : IUnitOfWork
{
public UnitOfWork()
{
this.Context = new MyEFEntities();
this.Context.ContextOptions.LazyLoadingEnabled = true;
}
public void Dispose()
{
this.Context.Dispose();
}
public ObjectContext Context { get; internal set; }
}
Setup your repository:
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class
{
public Repository(IUnitOfWork unitOfWork)
{
Context = unitOfWork.Context;
ObjectSet = Context.CreateObjectSet<TEntity>();
}
public ObjectContext Context { get; set; }
public IObjectSet<TEntity> ObjectSet { get; set; }
}
Register with Castle in Global.asax:
void Application_Start()
{
this.Container.Register(
Component.For<IUnitOfWork>()
.UsingFactoryMethod(() => new UnitOfWork())
.LifeStyle
.Is(LifestyleType.PerWebRequest)
);
ControllerBuilder.Current.SetControllerFactory(
new WindsorControllerFactory(this.Container));
}
And use in your controller (or wherever you're using it, as long as it's injectable):
public class SomeController
{
public SomeController(IRepository<MyEntity> repository)
{
this.Repository = repository;
}
public IRepository<MyEntity> Repository { get; set; }
public ActionResult MyAction()
{
ViewData.Model = this.Repository.ObjectSet.Single(x => x.Condition); //or something...
}
}
Any lazy loading here could potentially be a trap for a future issue. Without DI, without a repository - its hard to see anything working without it being a hack for lazy loading. Also do you you plan on passing your entities to your view. If so this is going to create a bad overlap. The controller should package data for your view, not have things evaluated later in your view.
For MVC best practices, you should flatten out your domain model as much as possible into a viewmodel (if flattening makes sense) and use the view model. Since you would ideally then know what would be lazy loaded, it may make more sense to take the hit up front and use .Include() in your query to eager load, otherwise you can issue many many queries to the database.
I've used a session factory pattern and saved the DBContext in the session object. It will stay open per session. I haven't had problems with it so far.
I am creating an application in mvc3 and wondering how to deal with database data which is required for all application requests, some of them depends on a session, some of them depends on url pattern basically all data is in database.
Like to know best practice
What I do in my applications and consider to be the best practice is to load your common data to the ViewBag on the Controller constructor.
For every project, I have a DefaultController abstract class that extends Controller. So, every controller in the project must inherit from DefaultController, instead of Controller. In that class' constructor, I load all data common to the whole project, like so:
// DefaultController.cs
public abstract class DefaultController : Controller
{
protected IRepository Repo { get; private set; }
protected DefaultController(IRepository repo)
{
Repo = repo;
ViewBag.CurrentUser = GetLoggedInUser();
}
protected User GetLoggedInUser()
{
// your logic for retrieving the data here
}
}
// HomeController.cs
public class HomeController : DefaultController
{
public HomeController(IRepository repo) : base(repo)
{
}
// ... your action methods
}
That way you will always have the logged in user available in your views.
I do the same as #rdumont but with one exception: I create a CommonViewModel which I use to define all common properties that I use.
public class CommonViewModel
{
public string UserName {get;set;}
public string Extension {get;set; }
}
Declare a property in the base controller:
public abstract class BaseController : Controller
{
protected CommonViewModel Commons { get; private set; }
protected virtual void OnResultExecuting(ResultExecutingContext filterContext)
{
ViewBag.Commons = Commons;
}
}
By doing so I get everything almost typed. The only cast that I need to do is to cast ViewBag.Commons to the CommonViewModel.
Best is to avoid ViewBag at all.
See this answer, which details how to use Html.RenderAction() for that purpose:
Best way to show account information in layout file in MVC3
I'd suggest using a base ViewModel class.
So a base class with properties/functions which should be available at any point.
I have ASP.NET MVC3 project where I want to use custom membership provider. Also I want to use Unity for resolving my dependency injection.
this is code from Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
var container = new UnityContainer();
container.RegisterType<IAuthentification, Authentification>();
container.RegisterType<IRepository, Repository>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
this is code from my membership provider:
public class CustomMembershipProvider : MembershipProvider
{
[Dependency]
private IProveaRepository Repository { get; set; }
public override bool ValidateUser(string username, string password)
{
.....
}
Problem is when I put breakpoint to ValidateUser method I see that Repository property not initialized. But this construction:
[Dependency]
private IProveaRepository Repository { get; set; }
for example, works fine in controllers.
Does anybody know why it is so and what to do?
I had the same problem over the last couple of days. I ended up with the following solution (type and field names changed to match yours).
public class CustomMembershipProvider : MembershipProvider
{
private IProveaRepository repository;
public CustomMembershipProvider()
: this (DependencyResolver.Current.GetService<IProveaRepository>())
{ }
public CustomMembershipProvider(IProveaRepository repository)
{
this.repository= repository;
}
public override bool ValidateUser(string username, string password)
{
...
}
}
So even though Unity is not in control of the building of the CustomMembershipProvider, the parameterless constructor gets Unity involed (via the MVC3 DependencyResolver) to supply the correct repository instance.
If you're unit testing the CustomMembershipProvider then you can just build an instance with Unity directly, which will use the second constructor and avoid the call to DependencyResolver.
Unity cannot inject IProveaRepository instance into you custom membership provider because :
You did not configured it to do so
CustomMembershipProvider is not resolved by unity so it has no control on injecting into it the dependencies
If you're using your membership priovider class in your code you could do the following :
Try to wrapp your customMembershipProvider in an abstraction for example IMembershipProvider that has only signature for methods that you use. The result is like that :
public class CustomMembershipProvider : MembershipProvider, IMembershipProvider
Then you could register it in unity :
container.RegisterType<IMembershipProvider, CustomMembershipProvider>(new InjectionProperty(new ResolvedParameter<IProveaRepository>()));
Then the constraint is to pass the dependency in your controller like that :
public class HomeController : Controller
{
private IMembershipProvider _membershipprovider;
public HomeController(IMembershipProvider membershipProvider)
{
_membershipProvider = membershipProvider
}
// some actions
}
But it would be event better to not user the property injection but the constructor injection like that :
public class CustomMembershipProvider : MembershipProvider
{
private IProveaRepository Repository { get; set; }
public CustomMembershipProvider(IProveaRepository proveaRepository)
{
Repository = proveaRepository
}
public override bool ValidateUser(string username, string password)
{
.....
}
It's the way I understand it and would do it. But maybe there is a better approach or I'm ignoring some of Unity API that would help to achieve it easier.
Anyway I hope it helps.
While as others said Unity cannot inject dependencies in providers because they're not known
to the container and, even if could be a registration of a provider, you haven't a "factory point" where building the provider through the container, there's a solution which doesn't violate good design principles. (This because, even if most people ignore this, using a ServiceFactory is too close to an antipattern...)
But, a good solution could be the association of using the [Dependency] attribute in conjunction with the Unity BuildUp method.
So taking your example, to get what you're trying to do, leave all the things as they are, and put in the provider constructor the BuildUp call
public class CustomMembershipProvider : MembershipProvider
{
[Dependency]
private IProveaRepository Repository { get; set; }
public CustomMembershipProvider()
{
//contextual obtained container reference
unityContainer.BuildUp(this);
.....
}
public override bool ValidateUser(string username, string password)
{
.....
}
I hope it helps.