The Spring documentation here discusses the use of a [Required] attribute to inject objects into code. I've removed injection through the constructor from my code and setup a setter as provided in the example. However, I cannot get this to work. Is anybody using this successfully ?
Related
In razor pages I'm using #inject Blazored.LocalStorage.ISyncLocalStorageService localStorage and it's working fine. But from non-razor connected classes (services and helpers) using
[Inject]
protected Blazored.LocalStorage.ISyncLocalStorageService localStorage { get; set; }
Always returns null. Is there something additional that is needed to get DI to work in non-Razor files? Or do I have to push all of the DI through Constructors all the way down from the UI layer?
The following is based only on my own experience, so I might be proved wrong...
Only constructor injection works in non-razor objects. Thus you cannot define a property annotated with the Inject attribute and expect it to be populated with an instance of a given object. Use constructor injection instead.
With Razor objects, however, you can use the #inject directive to inject services into Razor components, but you can also use the Inject attribute with properties in razor component class definition (.razor.cs ) and in #code blocks ( .razor ).
Hope this helps...
I swear to god, that I had seen something like (below) on one of the MSDN Article but I cant find this property attribute documentation anywhere.
public class MyViewModel{
[Required]
public bool Important {get;set;}
[ValidationDependsOn("Important")]
public bool HasVIPAccess {get;set;}
}
If you look at the above code (maybe a bad example), I am trying to establish a relationship between the two properties in such a way that validation of HasVIPAccess property depends on the validation of the property called Important.
the built in validation attribute that do something like that is [Compare("OtherProperty")] which means the property that you put this attribute on must equal OtherProperty
ex
public class MyViewModel{
[Required]
public bool Important {get;set;}
[Compare("Important")]
public bool HasVIPAccess {get;set;}
}
Note : Require MVC 3+
if you wanna other validation attributes you can check Mvc.ValidationTookit
if you want to understand the science behind it
this is new to mvc3 and you can implement your custom attribute like this fairly easy in mvc3
because IsValid now recives a ValidationContext parameter which contains information about the validation that is being performed like the type of the model and metadata associated with it so you can use reflection to get other properties and their value the CompareAttribute made use of this feature
FluentValidation.NET
You can do this by writing a custom validation attribute (this enables only server side validation)... Here is a relevant post Creating New Data Annotation Validation Attributes in MVC
However...if you want to get client side unobstrusive validation to work as well, then you need to do some javascript work...here is another post that talks about creating unobtrusive client side validation...Unobtrusive Client Validation with MVC 3
I'm trying to inject a repository to a custom membership provider with ninject in MVC 3.
In MembershipProvider I have tried the following:
[Inject]
public ICustomerRepository _customerRepository{ get; set; }
And
[Inject]
public TUMembershipProvider(ICustomerRepository customerRepository)
{
_customerRepository = customerRepository;
}
In my ninject module i tried the following:
Bind<MembershipProvider>().ToConstant(Membership.Provider);
None of the above works.
When i use(in global.asa)
kernel.Inject(Membership.Provider);
together with
[Inject]
public ICustomerRepository _customerRepository{ get; set; }
it works, but i have no life cycle management and this will cause a "ISession is open" error from NHibernate, because the ISession is InRequestScope and the repository is not.
You could use the approach #Remo Gloor outlines in his blog post on provider injection. It involves 3 steps:
Add [Inject]s to any properties on your provider you need injected (although the pattern he shows -- creating a very simple class whose only function is to be a receptable for property injection and forwards any requests to a real class implemented using constructor injection -- is well worth following)
public class MyMembershipProvider : SqlMembershipProvider
{
[Inject]
public SpecialUserProvider SpecialUserProvider { get;set;}
...
Create an initializer wrapper that implements IHttpModule which pulls the provider in, triggering its creation:-
public class ProviderInitializationHttpModule : IHttpModule
{
public ProviderInitializationHttpModule(MembershipProvider membershipProvider)
{
}
...
Register the IHttpModule in your RegisterServices :-
kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();
there is no 4; Ninject does the rest - bootstrapping all registered IHttpModules including the one you added) during the startup sequence.
(Don't forget to read the comments on the blog post re lifetimes etc.)
Finally, if you're looking for something completely braindead direct that solves it neatly, try this #Remo Gloor answer instead
PS a great writeup on the whole mess is Provider is not a Pattern by #Mark Seemann. (and the oboligatory plug for his excellent book:- Dependency injection in .NET which will have you figuring this stuff out comfortably from first principles)
i had this problem
a custom membership, role and profile provider in another project from MVC using repository, when ever i call the provider the injected repository was null.
tried to call kernel.Inject(Membership.Provider); in the NinjectWebCommon method registerServices(IKernel kernel) but got the exception
The result is always null, because asp.net has it's own static property for membership.which is membership.provider. and this instance is not part of instance ninject management.
so use on PostApplicationStartMethod
here is the soloution by cipto add to NinjectWebCommon the attrbute and method :
[assembly: WebActivator.PreApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "RegisterMembership")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebApp.App_Start.NinjectWebCommon), "Stop")]
public static void RegisterMembership()
{
bootstrapper.Kernel.Inject(Membership.Provider);
}
The problem is that the whole Membership infrastructure is a "native" .NET code (System.Web.Security) that does not know about MVC and about the DI container used by MVC.
The static call to Membership.Provider returns the membership provider based on the configuration, however, the specified provider type is instantiated with a simple Activator.CreateInstance call. Hence, the dependency injection has no chance to kick in and set your repository dependency on the result. If you explicitly setup the returned instance with Ninject it can work, because you explicitly gave Ninject the object to set the dependencies. Even in this case it can only work with property injection and not with constructor injection, because the instance is created by the membership configuration previously.
To summarize: you cannot easily inject dependencies into the membership provider because it is not resolved from a dependency injection container.
I think you have 2 possibilities:
You create a repository in the custom membership provider directly or you access it by some other means on demand (where the web context is already present).
You go one level higher and check the components that would use your membership provider and you try change there (to use a membership provider resolved from your DI container instead of the uninitialized Memership.Provider). If this "higher component" is the forms authentication, then this article might be of help (using dependency injection with IFormsAuthentication and IMembershipService): http://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx
Did you try resolving your repository "manually", like in this answer:
Ninject : Resolving an object by type _and_ registration name/identifier
?
I am a beginner using castle windsor; and kinda introduced to it with Apress Pro Mvc book. In the project that I am working at; I use castlewindsor controller factory instead of mvc controller factory; so i can have parametrized constructors and i can inject the dependencies.
Is there a way to tell the windsorcontroller factory to inject the values to the properties of the controller class without going through constructor?
The reason I want to do this is because I have Logging dependency; Emailler Dependency; Database Dependency; Theme Engine dEpendency; and I dont want to use this many parameters parameter in the constructor.
By default, when Windsor resolves a service implementation, it will populate all properties with public setters that it can satisfy.
However, take notice that sometime it does make sense to put the dependency resolving in the constructor, for that fact that it guarantees that any instance will always be in a valid state. Consider Unit Testing scenario, where the person writing the test will go crazy about the need to know which dependencies should be supplied. When all dependencies goes into the c'tor, the tester will have no choice but to supply the tested instance with all the required dependencies (as stubs or mocks).
Anyway, as for your question, Windsor support C'tor and property injection by default
Castle Windsor will automatically fill any properties with public setters that it knows how to fill.
This means if you have a class
public MyClass {
public SomeDependency {get; set;}
}
As long as the container is configured to know how to resolve SomeDependency it will attempt to resolve and inject it.
Sometimes I've found this default behavior to be hassle. This facility will give you finer grained control over the process.
Question
How do you handle read-only fields when creating fakes?
Background
I'm in the beginner stages of using ASP.Net MVC and am using Steven Sanderson's Sports Store and Scott Gu's Nerd Dinner as examples. One small problem that I've just hit is how to work with read-only properties when doing fakes. I'm using LINQToSQL.
My interface is:
public interface IPersonRespository
{
Person GetPerson(int id);
}
and my fake becomes
public class FakePersonRepository
{
public Person GetPerson(int id)
{
return new Person {id="EMP12345", name="John Doe", age=47, ssn=123-45-6789, totalDrWhoEpisodesWatched=42};
}
}
Here's my problem. The fields id, ssn and totalDrWhoEpisodesWatched are read-only, so the above code won't actually work. However, I don't recognize how to create a fake new person and set a read-only property. I'm sure there is a solution, but I haven't come across it yet in my searches.
Update: Inheritance + Property Hiding as a Potential Solution?
I haven't yet decided upon a firm solution to the problem. I dislike the notion of modifying my Domain classes for the purposes of creating fakes. To me, adding markup to the domain classes in order to do testing is a form of added coupling -- coupling to the implementation of your test. I'm now investigating another possibility, which is to create a FakePerson class, which inherits from Person, but hides the properties with new read-write properties.
public class FakePerson: Person
{
public new int age { get; set; }
public new string ssn { get; set; }
public new int totalDrWhoEpisodesWatched { get; set; }
}
So far, this solution is how I am leaning. It does break the Liskov Substitution Principle, however that doesn't bug me as much in a test project. I'd be glad to hear any criticism and/or feedback on this as a solution.
Winner: Mock Frameworks
Moq appears to do the job. My last solution of hiding the property through inheritance does, in fact, work, however by using Moq, I get a standardized set of functionality that is more maintainable. I assume that other mock frameworks have this functionality, but I haven't checked. Moq is said to be more straightforward for the beginning mock writing, which I definitely am right now.
Consider mocking the Person type in your test. Example using Moq:
var mock = new Mock<Person>();
mock.SetupGet(p => p.id).Returns("EMP12345");
mock.SetupGet(p => p.ssn).Returns("123-45-6789");
mock.SetupGet(p => p.totalDrWhoEpisodesWatched).Returns(42);
return mock.Object;
Otherwise, try finding out how LINQ to SQL sets those read only properties.
EDIT: If you attempt the above and Moq throws an ArgumentException in the SetupGet call with the message "Invalid setup on a non-overridable member: p => p.id", then you need to mark the property as virtual. This will need to be done for each property whose getter you wish to override.
In LINQ to SQL, this can be done in the OR designer by selecting the property, then in the Properties window set Inheritance Modifier to virtual.
You can only set readonly properties in the constructor of the class. The Person object should have a constructor that accepts id, ssn, and totalDrWhoEpisodesWatched. Of course, if this is a linqtosql generated object, you might have issues modifying that as the code is auto-generated.
You could consider using a mapped object to expose in your repository ... so you'd never actually have to use your linqtosql object as your model.
In .NET, you could mark your setters as "internal" and use the InternalsVisibleTo assembly attribute to make internals visible to your test assembly. That way your setters won't be public, but you can still access them.
note: even though the question isn't tagged .NET, I assumed it was based on your usage of object initializer syntax. If my assumption was wrong, this suggestion does not apply (unless the language you're using has an equivalent feature, of course).
If it's for tests - consider using reflection. That wouldn't involve messing around your domain model.
For example - i got FactoryBase class, which uses reflection to set needed prop by lambda expression through parameters (like this). Works like a charm - creating new factory is simple as defining repository type and default entity data.
I also use Moq. I love it and it works great. But, before I started using Moq, I wrote many fakes. Here's how I would have solved the problem using fakes.
Since a fake can have additional methods that the "production" implementation doesn't have, I would add a few extra methods to my fake implementation to handle setting the read-only portion.
Like this:
public class FakePersonRepository : IPersonRespository
{
private IDictionary<int, Person> _people = new Dictionary<int, Person>();
public Person GetPerson(int id) // Interface Implementation
{
return _people(id);
}
public void SetPerson(int id, Person person) // Not part of interface
{
_people.Add(id, person);
}
}