What happened to the ability to override default interface implementations in C# 8, .Net Core 3? [duplicate] - .net-core-3.0

Why is the behavior of Default Interface Methods changed in C# 8?
In the past the following code (When the Default interface methods was demo not released):
interface IDefaultInterfaceMethod
{
// By default, this method will be virtual, and the virtual keyword can be here used!
virtual void DefaultMethod()
{
Console.WriteLine("I am a default method in the interface!");
}
}
interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
void IDefaultInterfaceMethod.DefaultMethod()
{
Console.WriteLine("I am an overridden default method!");
}
}
class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}
class Program
{
static void Main()
{
IDefaultInterfaceMethod anyClass = new AnyClass();
anyClass.DefaultMethod();
IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
anyClassOverridden.DefaultMethod();
}
}
has the following output:
Console output:
I am a default method in the interface!
I am an overridden default method!
But with the C# 8 last version the code above is producing the following output:
Console output:
I am an overridden default method!
I am an overridden default method!
Anyone can explain to me why this behavior is changed?
Note:
IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();
((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??

I suspect a better question would be:
How can I call the default method instead of the concrete implementation?
The feature was planned but was cut from C# 8 in April 2019, because an efficient implementation would require support from the runtime. This couldn't be added in time before release. The feature would have to work well both for C# and VB.NET - F# doesn't like interfaces anyway.
if B.M is not present at run time, A.M() will be called. For base() and interfaces, this is not supported by the runtime, so the call will throw an exception instead. We'd like to add support for this in the runtime, but it is too expensive to make this release.
We have some workarounds, but they do not have the behavior we want, and are not the preferred codegen.
Our implementation for C# is somewhat workable, although not exactly what we would like, but the VB implementation would be much more difficult. Moreover, the implementation for VB would require the interface implementation methods to be public API surface.
It will work through a base() call similar to how classes work. Coopying the proposal example :
interface I1
{
void M(int) { }
}
interface I2
{
void M(short) { }
}
interface I3
{
override void I1.M(int) { }
}
interface I4 : I3
{
void M2()
{
base(I3).M(0) // What does this do?
}
}

Related

aop aspects as mock in spring test

I came across an interesting article: AOP Aspects as mocks in JUnit
Since I have requirement to mock multiple final and private static variables, I am planning to use AOP in place of reflection or PowerMockito as they are causing issues with SpringJUnit4ClassRunner.
Is there any way I can use #Aspect for test classes without using the annotation #EnableAspectJAutoProxy? (I want to use an aspect targeting class X only in one test case.)
This is a sample of what I want to do.
The question is answered(adding for discussion on what could be done)
//External class
public final class ABC(){
public void method1() throws Exception {}
}
#Service
public void DestClass() {
private static final ABC abc = new ABC();
public Object m() {
// code (...)
try {
abc.method1();
}
catch(Exception e) {
// do something (...)
return null;
}
// more code (...)
}
}
Spring framework allows to programmatically create proxies that advise target objects , without configuring through #EnableAspectJAutoProxy or <aop:aspectj-autoproxy>
Details can be found in the documentation section : Programmatic Creation of #AspectJ Proxies and the implementation is pretty simple.
Example code from the documentation.
// create a factory that can generate a proxy for the given target object
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);
// add an aspect, the class must be an #AspectJ aspect
// you can call this as many times as you need with different aspects
factory.addAspect(SecurityManager.class);
// you can also add existing aspect instances, the type of the object supplied must be an #AspectJ aspect
factory.addAspect(usageTracker);
// now get the proxy object...
MyInterfaceType proxy = factory.getProxy();
Please note that with Spring AOP , only method executions can be adviced. Excerpt from the documentation
Spring AOP currently supports only method execution join points
(advising the execution of methods on Spring beans). Field
interception is not implemented, although support for field
interception could be added without breaking the core Spring AOP APIs.
If you need to advise field access and update join points, consider a
language such as AspectJ.
The document shared with the question is about aspectj and without providing the sample code to be adviced it is hard to conclude if the requriement can acheived through Spring AOP. The document mentions this as well.
One example of the integration of AspectJ is the Spring framework,
which now can use the AspectJ pointcut language in its own AOP
implementation. Spring’s implementation is not specifically targeted
as a test solution.
Hope this helps.
--- Update : A test case without using AOP ---
Consider the external Class
public class ABCImpl implements ABC{
#Override
public void method1(String example) {
System.out.println("ABC method 1 called :"+example);
}
}
And the DestClass
#Service
public class DestClass {
private static final ABC service = new ABCImpl();
protected ABC abc() throws Exception{
System.out.println("DestClass.abc() called");
return service;
}
public Object m() {
Object obj = new Object();
try {
abc().method1("test");
} catch (Exception e) {
System.out.println("Exception : "+ e.getMessage());
return null;
}
return obj;
}
}
Following test class autowires the DestClass bean with overridden logic to throw exception . This code can be modified to adapt to your requirement.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { DestClassSpringTest.TestConfiguration.class })
public class DestClassSpringTest {
#Configuration
static class TestConfiguration {
#Bean
public DestClass destClass() {
return new DestClass() {
protected ABC abc() throws Exception {
// super.abc(); // not required . added to demo the parent method call
throw new Exception("Custom exception thrown");
}
};
}
}
#Autowired
DestClass cut;
#Test
public void test() {
Object obj = cut.m();
assertNull(obj);
}
}
Following will be the output log
DestClass.abc() called // this will not happen if the parent method call is commented in DestClassSpringTest.TestConfiguration
Exception : Custom exception thrown
The article you are referring to is using full AspectJ, not Spring AOP. Thus, you do not need any #EnableAspectJAutoProxy for that, just
either the AspectJ load-time weaver on the command line when running your test via -javaagent:/path/to/aspectjweaver.jar
or the AspectJ compiler activated when compiling your tests (easily done via AspectJ Maven plugin if you use Maven)
Both approaches are completely independent of Spring, will work in any project and even when using Spring also work when targeting execution of third party code because no dynamic proxies are needed unlike in Spring AOP. So there is no need to make the target code into a Spring bean or to create a wrapper method in your application class for it. When using compile-time weaving you can even avoid weaving into the third party library by using call() instead of execution() pointcut. Spring AOP only knows execution(), AspectJ is more powerful.
By the way: Unfortunately both your question and your comment about the solution you found are somewhat fuzzy and I do not fully understand your requirement. E.g. you talked about mocking final and private static variables, which would also be possible in other ways with AspectJ by using set() and/or get() pointcuts. But actually it seems you do not need to mock the field contents, just stub the results of method calls upon the objects assigned to those fields.

How to reduce slow start for picocli apps due to reflection

Picocli has to introspect the command tree. Doing so it needs to load the domain object classes for every Command which slows down the jvm startup.
What options are there to avoid this startup lag? One solution I've come up with is described in https://github.com/remkop/picocli/issues/482:
I am using reflection to postpone any class loading until after the command is selected. This way only the command classes themselves are loaded and finally the classes which implement the single command requested by the user:
abstract class BaseCommand implements Runnable {
interface CommandExecutor {
Object doExecute() throws Exception;
}
// find the CommandExecutor declared at the BaseCommand subclass.
protected Object executeReflectively() throws Exception {
Class<?> innerClass = getExecutorInnerClass();
Constructor<?> ctor = innerClass.getDeclaredConstructor(getClass());
CommandExecutor exec = (CommandExecutor) ctor.newInstance(this);
return exec.doExecute();
}
private Class<?> getExecutorInnerClass() throws ClassNotFoundException {
return getClass().getClassLoader().loadClass(getClass().getName() + "$Executor");
}
public void run() {
try {
executeReflectively();
} catch(...){
/// usual stuff
}
}
}
A concrete commend class:
#Command(...)
final class CopyProfile extends BaseCommand {
#Option String source;
#Option String dest;
// class must NOT be static and must be called "Executor"
public class Executor implements CommandExecutor {
#Override
public Object doExecute() throws Exception {
// you can basically wrap your original run() with this boilerplate
// all the CopyProfile's field are in scope!
FileUtils.copy(source, dest);
}
}
}
It seems like https://github.com/remkop/picocli/issues/500 may provide the ultimate solution to this. What are the other options until then?
UPDATE February 2020:
Upgrading to a recent version of picocli should fix this issue.
From the picocli 4.2.0 release notes:
From this release, subcommands are not instantiated until they are matched on the command line. This should improve the startup time for applications with subcommands that do a lot of initialization when they are instantiated.
An alternative that doesn’t require any code changes is to use GraalVM to compile your picocli-based application to a native image.
This article shows how to do this and the resulting startup time is 3 milliseconds.

GetControllerName not being called in derived DefaultHttpControllerSelector implementation

I'm attempting to do versioning with ASP.NET Web API. I have created a simple controllerselector that derives from DefaultHttpControllerSelector.
public class MyHttpControllerSelector : DefaultHttpControllerSelector
{
public MyHttpControllerSelector(HttpConfiguration config) : base(config) { }
public override string GetControllerName(HttpRequestMessage request)
{
return "SomeControllerName";
}
}
In my WebApiConfig.Register:
config.MapHttpAttributeRoutes();
config.Services.Replace(typeof(IHttpControllerSelector), new MyHttpControllerSelector(config));
My problem is GetControllerName is never called. I may be misunderstanding the intent of this function, but I have seen plenty of examples, some right from Microsoft that use this method.
What am I missing?
In my case it was because I was not calling config.Routes.MapHttpRoute(). I was just using Attribute Routing. Once I used MapHttpRoute() it seemed to start calling GetControllerName.

Where to put View logic in MVP?

So I am implementing MVP in ASP.NET webforms.
I need to be able to change the color of a label based on the status of some data.
My first attempt:
class Presenter
{
...
_view.IsStatusTrue = true;
}
class View
{
bool IsStatusTrue
{
set
{
if(value)
{
lbl.Text = "Status is true :)";
lbl.CssClass = "trueClass";
}
}
}
}
My question: is this logic supposed to be in the Presenter?
class Presenter
{
...
if(status == true)
{
_view.LblCssClass = "trueClass";
_view.StatusText = "Status is true :)";
}
}
Your post title is self-answering indeed, and it's the view responsibility. I develop a home pet MVP framework project in Java, and the very core of the framework is platform-independent as well as my apps using the framework are. This lets me have many implementations for the target platform/apps views: Swing (something similar to WinForms from the .NET world), GWT (Java to JavaScript infrastructure), JSF (~ASP.NET MVC), Android, JavaFX (~WPF), Lanterna (text-mode user interface) and pure CLI (command-line interface). Think of your presenters as if they all are completely platform-independent. From this point of view, your first example is better than the second one. What it gives:
This means that the view does not reveal how it would report the status. This lets the presenter know as less as possible about the view. A simple boolean IsSuccessful{ set; } is really enough to report the status. If you reveal its components, then you violate encapsulation really much.
If your presenters are platform-independent, you can unit-test them easily at your platform not starting the target runtime and even not referencing the target runtime libraries, so they are pure. In this case you'd just need to mock your view.
You might want to port some your base code to another runtime, not necessarily ASP.NET. Let's say, WinForms. Having your second example introduced it wouldn't work (e.g. trueClass cannot be applied to WinForms, right?). Just consider the following code:
public sealed class CliView
: AbstractCliView, // just an example, it might containt CLI-related stuff
IStatusView {
public boolean IsSuccessful {
set {
Console.ForegroundColor = value ? ConsoleColor.Green : ConsoleColor.Red;
Console.WriteLine(value ? "success" : "FAILURE");
Console.ResetColor();
}
}
}
This is possible just because in the first case you encapsulate how a view is implemented and not reveal the implementation details. What if you would like to support an audio interface someday? :)
public class Presenter
{
bool _status;
IView _view;
public Presenter(IView view)
{
_view = view;
if (_status)
{
_view.LabelColorCode = "#c2d8ff";
_view.LabelText = "Status is true";
}
}
}
public interface IView
{
string LabelColorCode { set; }
string LabelText { set; }
}

Handling specimen creation inconsistencies between AutoFixture and Moq

I am using AutoMoqCustomization in my test conventions.
Consider the code below. Everything works great until I add a constructor to one of the concrete classes. When I do, I get "could not find a parameterless constructor". We know AutoFixture doesn't have an issue with the constructor because it delivered me the test object one which proved to be assignable from IThings... no failure there. So it must be moq.
This makes some sense because I assume builder was generated by moq and passed into the GetCommands method. So I think I can see that control has been passed from AutoFixture to moq at that point.
That takes care of the why, but what should I do about it? Is there a way to instruct moq on how to deal with the ThingOne or is there a way to instruct AutoFixture to ignore moq for IThingBuilders and instead do something Fixtury?
public class TestClass
{
public interface IThingBuilders
{
T1 Build<T1>() where T1 : IThings;
}
public interface IThings
{
}
public class ThingOne : IThings
{
public ThingOne(string someparam)
{
}
}
public class ThingTwo : IThings
{
}
public class SomeClass
{
public List<IThings> GetCommands(IThingBuilders builder)
{
var newlist = new List<IThings>();
newlist.Add(builder.Build<ThingOne>());
newlist.Add(builder.Build<ThingTwo>());
return newlist;
}
}
[Theory, BasicConventions]
public void WhyCannotInstantiateProxyOfClass(ThingOne one, ThingTwo two, IThingBuilders builder, SomeClass sut)
{
Assert.IsAssignableFrom<IThings>(one);
Assert.IsAssignableFrom<IThings>(two);
var actual = sut.GetCommands(builder);
Assert.Equal(1, actual.OfType<ThingOne>().Count());
Assert.Equal(1, actual.OfType<ThingTwo>().Count());
}
}
As there's no extensibility point in Moq that enables AutoFixture to hook in and supply a value of ThingOne, there's not a whole lot you can do.
However, you can use the SetReturnsDefault<T> method of Moq. Modifying the above test would then be like this:
[Theory, BasicConventions]
public void WhyCannotInstantiateProxyOfClass(
ThingOne one, ThingTwo two, IThingBuilders builder, SomeClass sut)
{
Assert.IsAssignableFrom<IThings>(one);
Assert.IsAssignableFrom<IThings>(two);
Mock.Get(builder).SetReturnsDefault(one); // Add this to make the test pass
var actual = sut.GetCommands(builder);
Assert.Equal(1, actual.OfType<ThingOne>().Count());
Assert.Equal(1, actual.OfType<ThingTwo>().Count());
}
This is a bit easier than having to write a specific Setup/Returns pair, but not much. You could move that code to an AutoFixture Customization, but again, since this is a generic method on a a Mock instance, you'll explicitly need to call this for e.g. ThingOne in order to set the default for that return type. Not particularly flexible.

Resources