C#: Using WriteError and WriteVerbose in non-cmdlet inheriting class - c#

Apologies for the seemingly odd Title on this. I'm creating some PowerShell modules in C# and I'm getting rather stuck on the above. In BeginProcessing, ProcessRecord etc, I can call WriteWarning, WriterError and WriteVerbose. However, if I want to add Warnings, Errors etc to any of my custom classes, which are instantiated in the above, then I cannot call these because they're not inheriting from cmdlet. I've spent ages searching for an answer on this, but I cannot find the answer. I found an msdn blog post that wrote about this, but they just called these from within ProcessRecord.
I'm guessing I need to send the messages back to ProcessMessage using a pipeline, but I don't understand how I should do this. Can anybody give me any tips on what/how I should be doing ?

You could pass a Func/delegate of the method(s) that you need to your other custom classes. Ideally you want to wrap all of that up in your own ILogger class that you then implement and pass on to your classes. Or you could just pass the class itself to your other custom classes since the methods that you want to call on it are public.

Related

How to assign attribute to classes methods by convention?

I wanted to make my Controller methods register as [HttpGet] if they have "get" in the method name, the same goes for [HttpPost] if they have "create" etc.
How can I create an "attributeAssigner", that would go over the assembly and do the job?
In fact you can't. The example Ygalbel mentioned is a solution which, to my opinion is kind of cheat.
The code in the example creates another class (a proxy) which inherits from the class you want to apply the attribute(s) to. In fact, if you use reflection to retrieve the custom attributes decorating your class (its properties and methods) you'll find none of them. The instance of a class in the suggested solution is instance of another class, not yours!
I'm not 100% sure, but I can guess ASP.NET (Core) does exactly this, so it'll find no attributes decorating your controller's actions.
In order to use the suggested solution you'll need to write some code which will have to do the following:
Inspect your controller class and figure out where to add the attributes as you want,
Use the solution described in the example,
Unregister the original controller a part,
Register the proxy created by the example code as substitute to the original with the provider.
Maybe this text could be a good starting point but still, your idea needs to be clarified.
Anyway, if you do insist on its implementation I wish you good luck. This is part of the advanced topics in ASP.NET Core.
HTH

How to spy the class under test with AutofacContrib.NSubstitute

I'm running unit tests in a class library project with NSpec framework, AutofacContrib.NSubstitute v3.3.2.0, NSubstitute v1.7.0.0 (the latest as of now is 1.8.2).
The Class Under Test instance is built with AutoSubstitute, in order to automock all its needed dependencies.
AutoSubstitute autoSubstitute = new AutoSubstitute();
MainPanelViewModel viewModel = autoSubstitute.Resolve<MainPanelViewModel>();
If working properly, my Class Under Test at some point will invoke one of it's base class methods with some specific input parameter (the base class is out of my control):
// ...
base.ActivateItem(nextScreen);
// ...
So, for test expectation, I need to check (spy) that the instance invokes the base method:
viewModel.Received().ActivateItem(Arg.Any<SomeSpecificScreenType>());
Here's the problem: when I try to do this, at runtime NSubstitute complains that I can only ran Received() against an object created with Substitute.For<>(). I also checked quickly AutofacContrib.NSubstitute source code, but I could not find a way to obtain the instance with automocking and at the same time wrap it somehow in a spy object or something like that.
I also thought that maybe Substitute.ForPartsOf<>() could be helpful, but that method does not seem to be found in NSubstitute v1.7.0.
For sake of completeness, here's NSubstitute full error:
NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods.
For completeness, I did some experimenting with NSubstitute's partial substitutions with ForPartsOf.
The way ForPartsOf works is essentially to define a new class that inherits from the class you're using as a template. This restricts what it is that the mocking framework can intercept to methods that are either defined as abstract or virtual. This is the same limitation you would have for modifying the behaviour of a class if you were to inherit from it with your own class.
Taking this information, lets look at your problem. You want to intercept this call:
base.ActivateItem(nextScreen);
So, because of the limitations above, for you to be able to intercept a call to ActivateItem, the method has to be marked as virtual in the base class. If it's not, there's nothing you can do without changing the application structure.
If the method is marked as virtual, then you can intercept it with NSubstitute but you can only do it if the NSubstituted implementation is called. This works through normal method dispatch, because the highest level implementation of a virtual method is called (the one provided by NSubstitute) when you invoke it. However, it doesn't work when you're calling the method via the base reference.
So, whilst you could intercept this:
ActivateItem(nextScreen)
You simply can't intercept this:
base.ActivateItem(nextScreen);
The fact that you're using base.ActivateItem in your code suggests that your class under test has its own implementation of the method that you don't want to call, so with your current tools you can't achieve what you were trying to do. Which is why it's a good thing that you found a workaround.
You're in the same situation with most other mocking frameworks, including Moq. The exception is TypeMock, which uses a totally different way to intercept method calls which means that it can do things that other frameworks simply can't.
So, the actual issue has not been really solved: it's just that the issue itself disappeared.
In order to check for correct behaviour, I recalled that I could also resort to an ActiveItem public property from base class, so with that I stopped using Receive() and went back to simple value comparison.
Still, for future reference, I did not find a way to spy the Class Under Test with these libraries. I know that spying the class under test should be avoided, but as with many things, sometimes you need to do that.
HTH

How to intercept method calls in C#

I'd like to intercept and inject custom code when calling 3rd party code in C#. I am using an external library (AutoIt) for GUI automation. The AutoIt dll is provided without source code.
All actions done with this framework are performed from a single class (AutoItClass) providing access to all the methods. I'd like to be able to inject custom code when calling methods on this class, is this possible? For example:
Log some information from within the called method.
Perform any other action from within the method (wait for X seconds).
This would be possible very simply by inheriting from this class and overriding all its methods (which is a must since this is a COM object), but this is not the preferred way. Any comments will be helpful!
I wouldn't use inheritance - you can use composition here. Create your own class which has the same methods - or in fact only the ones you're interested in - and delegate through that. That way you can be sure you won't "miss" any methods accidentally, because anything you don't implement won't be callable through the rest of your codebase... so long as you make sure the rest of your code doesn't refer to the original library class, of course.
You can investigate PostSharp, which is a commercial product that can inject IL into compiled assemblies to perform aspect oriented programming. You can define different kind of behaviour that should happen before and after a method gets executed, for example, which seems to be what you want. This way, as PostSharp handles this in a post-compilation step, you don't need to create any inherited classes from the classes that you want to intercept.
Otherwise if you want a more "pure" solution I would follow Jon's advice about creating a new class that wraps the functionality of the one that you want to intercept. (see Decorator pattern) .

How should comments for interface and class methods be different

I ran into this dilemma when working on an ASP.net web application using Web Client Software Factory(WCSF) in C#, and the same could apply to other platform and languages. My situation is like this:
I am defining an IView interface for each web page/user control based on WCSF paradigm, then have the page class implement the IView interface, basically implementing each of the methods defined in the interface. When I tried to add xml-documentation on the method level, I found myself basically repeating the same comment content for both interface method, and its counter-part in the implementing class.
So my question is: should there be some substantial difference between the documentation content on the interface method and corresponding class method? Should they be emphasizing on different aspect or something?
Somebody told me that the interface method comment should say "what" the method is supposed to do, and the class method comment should say "how" it does it. But I remember reading somewhere before that the method level comment should only say "what" the method is supposed to do, never the implementation detail of the method, since the implementation should not be a concern for method users and it might change.
Personally, I think these comments should be the same - both should say "what the method is going to do", in your terms.
There is no reason for XML comments to mention implementation details. The one exception, potentially, would be to mention potential side effects (ie: this method may take a long time), but I personally would do that in the <remarks> section of the XML doc comments.
Call me a nut but I'd use a descriptive name for the method and call it a day (no comments for either). I might add comments to the implementation if something about it is surprising or why its there is nonobvious.

How to replace boiler-plate code with attributes?

We have this pattern everywhere in our code:
using (ServiceAccess ws = new ServiceAccess())
{
//...
//code here to talk to webservice ws
//...
}
How can I replace this boiler plate code with an attribute on the functions that need to talk to the web service? (I'm thinking back to when I did some stuff with Hibernate in Java a long time ago and there was an some "Transation" annotation you could use that would auto-insert some try...catch boiler-plate code into the function.) The using {} is pretty good already but it would be nice to not have it at all... Having an attribute would also help document the function as one that talks the web service as opposed to one that does.
Edit: Would AOP do the trick?
Take a look at aspects in spring.net.
You can also take a look at PostSharp.
I't will let you use attributes to implement aspects, you can use it to achieve what you want.
I think the best you can do is create a shortcut for inserting that code as a snippet. You can't shoehorn a variable declaration into a method via an attribute. Or put another way, attributes can only tell you things about the code. They can't change the code itself.
"Aspect" type things...this is a way to decorate a given method with code of your choice. If you wanted to dispose e.g. after invocation of your method, the aspect as well as the code would have to have access to the Service. It would also mean that you have little control of the lifetime of the service class.
In some code lately I provide a context to my class through which service instances can be obtained. They are provided to a delegate you may pass. Any disposal can then be made after your closure is left...
DateTime serverTime;
context.UseService<IInfoService>(s=>serverTime = s.GetTime());

Categories