I am trying to use MEF conventions within the .NET Framework 4.5 and am stuck on something I thought should be simple.
I want to export a set of classes and all are working except for the one that has more than one constructor so MEF by default calls the constructor with the most parameters which is causing a break as the parameters are aren't importing which is how it should be I guess.
Anyway, I want to make sure it works by telling MEF to export the constructor with no parameters.
var registration = new RegistrationBuilder();
registration.ForTypesDerivedFrom<TestStepResult>()
.Export<TestStepResult>()
.SelectConstructor(xxx);
So I know I need to do something in the SelectConstructor but cannot find what should be there to say to call the constructor with no parameters.
One way to do this is:
registration.ForTypesDerivedFrom<TestStepResult>()
.Export<TestStepResult>()
.SelectConstructor(ctorInfos =>
{
var parameterLessCtor = ctorInfos.FirstOrDefault(ci => ci.GetParameters().Length == 0);
if (parameterLessCtor != null)
return parameterLessCtor;
else
return ctorInfos.First();
});
Note that it include some simple error handling. If there is no parameterless .ctor it returns the first one available. This might not be what you need though. You will have to decide on how to handle this case.
Can you not simply decorate the preferred constructor with the [ImportingConstructor] attribute?
AFAIK, the only step you're missing is:
registration.ForTypesDerivedFrom<TestStepResult>()
.Export<TestStepResult>()
.SelectConstructor(ctorInfos => ctorInfos[0]);
Where ctorInfos is contains the array of ctors you have for the export in question.
Related
I am trying to dynamically add field properties to a record class that I am also building dynamically using FileHelpers.Dynamic.DelimitedClassBuilder. I have no issues creating the class object and I currently add a field using the AddField(String) method.
As my apps grows I now have a need to declare specific field properties in various situations. So in the same sense I wanted to use FileHelpers.Dynamic.DelimitedFieldBuilder to create a field object and then pass that to my DelimitedClassBuilder object using the method AddField(DelimitedFieldBuilder).
However I am unable to instantiate a new object using FileHelpers.Dynamic.DelimitedFieldBuilder. When I issue the following code I get an error stating that DelimitedFieldBuilder does not contain a constructor that takes two arguments.
FileHelpers.Dynamic.DelimitedFieldBuilder fb = new FileHelpers.Dynamic.DelimitedFieldBuilder("ClassName", "Type");
Looking at the documentation it appears that this class does only have properties associated with it, so I am kind of stuck on how to actually implement this. It seems like it should be fairly easy but I cant seem to figure it out. Thanks for any help.
Not familiar with that functionality of file helpers; however, in the vast majority of functions/methods across .NET there is usually a way to assign properties after the class is instantiated.
Try something like this:
FileHelpers.Dynamic.DelimitedFieldBuilder fb = new FileHelpers.Dynamic.DelimitedFieldBuilder();
fb.Whatever = "ClassName";
fb.otherwhatever = "Type";
Just a stab. I have no idea if it will work or not.
The constructors of DelimitedFieldBuilder are internal so you'll run into difficulty with your approach. However AddField(String) returns a DelimitedFieldBuilder, so you might be able to use that.
It might be easier to make your own class MyFieldBuilder which calls the standard AddField(String).
I am able to get a list of all the registered types by doing
var myTypes = kernel.Get<List<IMyInterface>>();
The MyType implementations need to take in a constructor argument though. I thought I could accomplish this by doing
kernel.Get<List<IMyInterface>>(
new ConstructorArgument("argName", argValue ) );
but this doesn't seem to work. I get an exception saying it's trying to resolve the parameter "argName" and can't. I'm guessing it's trying to use that arg for the List, and not each type in the list.
Is there a way to do this?
Update:
I'm able to do this in a round about way by doing
var types =
from t in typeof(IMyInterface).Assembly.DefinedTypes
where typeof(IMyInterface).IsAssignableFrom(t)
where t.IsClass
select (IMyInterface)kernel.Get(t,
new ConstructorArgument("argName", argValue));
This is not ideal.
Update:
I ended up changing my class constructor to not take in the parameter. I think it was not a good DI practice the way I had it working.
You can specify constructor arguments in the type Bindings
kernel.Bind<IMyInterface>().To<MyType>().WithConstructorArgument("argName",argValue);
With that binding in place, argValue will be injected into MyType constructor.
UPDATE:
If the argument is known only in runtime, you could do it like this:
In the binding get the value for construtor from request parameters:
kernel.Bind<IMyInterface>().To<MyType>().WithConstructorArgument("argName",
r => r.Parameters.First().GetValue(r.Request.ParentContext, r.Request.Target));
When creating instance, pass the parameter into request:
kernel.Get<List<IMyInterface>>( new Ninject.Parameters.Parameter("argName",argValue) );
If you want all registered types you should use GetAll<T> instead of Get<List<T>>:
kernel.GetAll<IMyInterface>(new ConstructorArgument("argName",argValue));
you can materialize that as a list if you really need to using LINQ's ToList.
I just started working with Unit Testing with NMock
I one my test cases involve adding an entry in a dictionary which is then passed to the unit being tested. I define the map as:
var item = new Mock<MyClass>().Object;
var myMap = new Dictionary<MyClass, IList<MyOtherClass>>
{
{ item, completionRequirement }
};
However when I do a myMap.ContainsKey(item) inside the unit being tested it returns false.
I am able to view a proxied item in the Dictionary on inspecting it. I am guessing that I need to do something else as well on the mocked item.(Most probably define .Equals(object o)).
My question is :
How do you define the Equals(object o) for the mocked item.
Or is there a different solution to the problem altogether.
You might want to mock the dictionary as well. That is, refactor to use IDictionary<MyClass,IList<MyOtherClass>, then pass in a mocked dictionary. You can then set up expectations so that it returns mocked objects as necessary.
It's also possible that you may not need to use a mock at all in this instance. It's not possible to tell from what you've given us, but I've often found that people new to mocking can sometimes forget that you can use the real objects as well if those objects don't have cascading dependencies. For example, you don't really need to mock a class that's just a simple container. Create one and use it, instead. Just something to think about.
The approach given at http://richardashworth.blogspot.com/2011/12/using-reflection-to-create-mock-objects.html is in Java, but presents another approach to this problem using Reflection.
I like the idea of setting up a 'fake' object along the lines of what tvanfosson is suggesting.
But if you want to do it with a mocking framework, I think all you need to do is setup an expectation for what item.Object should be. In Rhino Mocks the syntax would be something like:
var knownObject = "myKey";
var mock = MockRepository.GenerateStub<IMyClass>();
mock.Stub(x=>x.Object).Return(knownObject);
That said, I have no idea what the equivalent code would be in NMocks, but it shouldn't be hard to figure it out if you're working with it (you can always ask a question on the user group).
HTH
I've been using Moq framework in c# for mocking in unit tests however there is one thing I dont complete understand yet. I have this line of code
var feedParserMock = new Mock<ApplicationServices.IFeedParser>();
feedParserMock.Setup(y => y.ParseFeed(csv)).Returns(items).Verifiable();
The second line does it mean it will only return the value if the parameter passed is the same? because the parameter that I pass to ParseFeed inside my controller is build inside the controller and I dont have access to it in the unit test. Currently the method is returning null, is there any way to specify I want to return my items variable no matter what the parameter is?
Yes. Moq provides the It static class that has helper methods for specifying parameters that satisfy certain criteria. Your example could be:
feedParserMock.Setup(y => y.ParseFeed(It.IsAny<string>())).Returns(items).Verifiable();
Then Moq will match your setup, given that the parameter is of the specified type and non-null (I chose string here, you should of course replace that with the correct type of your parameter in order for the code to compile).
You can also pass a delegate that Moq will evalute in order to determine if the setup is a match. Example:
feedParserMock.Setup(y => y.ParseFeed(It.Is<string>(s => s.Length > 3));
This will match any method invocations on ParseFeed, where the parameter is a string with a Length larger than 3.
Check out the "Matching arguments" section of the Moq Quickstart guide to learn more.
Yes, you can Use It.IsAny()
for example
feedParserMock.Setup(y => y.ParseFeed(It.IsAny<string>())).Returns(items).Verifiable();
Basically I'm trying to implement some sort of poor man's Aspect Oriented Programming in C#. I had thought about using a ContextAttribute but they seem only be be bound at the class level. Is there any way that I can put an attribute in such that it will receive the same parameters as the method which it annotates or some way to access the context in which it fired?
I have this code
public void AddUser(User user)
{
var errors = DataAnnotationsValidationRunner.GetErrors(user);
if (errors.Any())
throw new RulesException(errors);
users.Add(user);
}
from which I would like to extract the first 3 lines so I had something like
[Validated]
public void AddUser(User user)
{
users.Add(user);
}
I think you are missing a third component. Most AOP implementations (e.g. Aspect#) rely on a proxy or interceptor to actually execute the code. In your scenario, you lack whichever component needed to 1) know the attribute exists on the method, and 2) trigger the mechanism (or become it) needed to execute the code within the attribute.
Fortunately, there are already many (fairly) simple solutions available in open source. The simplest option I can think of would be to use a compile-time weaver like PostSharp. Grab a copy of that, and in the samples you'll find several examples of exactly what you are trying to do (you'd be interested in the OnMethodInvocationAspect).
The end result is that your code looks exactly like it does in the sample you provided, yet it's also running the code you wish.
Don't know exactly how your solution should look like, but in C# attributes do not execute code as long as you don't request them (as far as I know). And if you query for the attribute, you also have the context. So there is something wrong with your strategy in my opinion.