SearchDomainFactory.Instance is obsolete: 'Inject me!' ( Can't find out how to create instance) - resharper

I'm in the process of trying to migrate a R# extension project from R# 6 to R# 8. (I've taken over a project that someone wrote, and I'm new to writing extensions.)
In the existing v6 project there is a class that derives from RenameWorkflow, and the constructor used to look like this;
public class RenameStepWorkflow : RenameWorkflow
{
public RenameStepWorkflow(ISolution Solution, string ActionId)
: base(Solution, ActionId)
{
}
This used to work in R# SDK v 6, but now in V8, RenameWorkflow no longer has a constructor that takes Solution and actionId. The new constructor signature now looks like this;
public RenameWorkflow(
IShellLocks locks,
SearchDomainFactory searchDomainFactory,
RenameRefactoringService renameRefactoringService,
ISolution solution,
string actionId);
now heres my problem that I need help with (I think)
I've copied the constructor, and now the constructor of this class has to satisfy these new dependancies. Through some digging I've managed to find a way to satisfy all the dependencies, except for 'SearchDomainFactory'. The closest I can come to instantiating via the updated constructor is as follows;
new RenameStepWorkflow(Solution.Locks, JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance, RenameRefactoringService.Instance, this.Solution, null)
All looks good, except that JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance is marked as Obsolete, and gives me a compile error that I cannot work around, even using #pragma does not allow me to compile the code. The exact error message I get when I compile is Error 16 'JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance' is obsolete: 'Inject me!'
Obvious next question..ok, how? How do I 'inject you'? I cannot find any documentation over this new breaking change, in fact, I cannot find any documentation (or sample projects) that even mentions DrivenRefactoringWorkflow or RenameWorkflow, (the classes that now require the new SearchDomainFactory), or any information on SearchDomainFactory.Instance suddenly now obsolete and how to satisfy the need to 'inject' it.
Any help would be most appreciated! Thank you,
regards
Alan

ReSharper has its own IoC container, which is responsible for creating instances of classes, and "injecting" dependencies as constructor parameters. Classes marked with attributes such as [ShellComponent] or [SolutionComponent] are handled by the container, created when the application starts or a solution is loaded, respectively.
Dependencies should be injected as constructor parameters, rather than using methods like GetComponent<TDependency> or static Instance properties, as this allows the container to control dependency lifetime, and ensure you're depending on appropriate components, and not creating leaks - a shell component cannot depend on a solution component for instance, it won't exist when the shell component is being created.
ReSharper introduced the IoC container a few releases ago, and a large proportion of the codebase has been updated to use it correctly, but there are a few hold-outs, where things are still done in a less than ideal manner - static Instance properties and calls to GetComponent. This is what you've encountered. You should be able to get an instance of SearchDomainFactory by putting it as a constructor parameter in your component.
You can find out more about the Component Model (the IoC container and related functionality) in the devguide: https://www.jetbrains.com/resharper/devguide/Platform/ComponentModel.html

Related

Why is InvocationInterceptor active in dev-mode?

Today, while profiling a Quarkus app, I found out that io.quarkus.arc.runtime.devconsole.InvocationInterceptor seems to intercept (almost?) all bean classes when Quarkus is running in dev mode, even though the Interceptor has an InterceptorBinding that is not used anywhere in the application code.
#Inherited
#InterceptorBinding
#Target({ TYPE, METHOD })
#Retention(RUNTIME)
public #interface Monitored {
}
#Priority(Interceptor.Priority.LIBRARY_BEFORE)
#Monitored
#Interceptor
public class InvocationInterceptor {
//...
}
Can somebody explain to me why that is the case? I can't really tell if this is intended behaviour or a bug. Is the InterceptorBinding automatically sprinkled around my app during the build? I looked through the code, but could not find a place where that happened.
Why am I interested in that? The bookkeeping this interceptor does uses a CopyOnWriteArrayList (inside Invocation.Builder) which, in a hot loop will quickly generate tens of thousands of copies of that list. Today, that confused the heck out of me while I was profiling the app, because the memory requirements were so drastically different between prod and dev mode.
(If relevant: All of this happened with Quarkus 2.7.3.Final)
This is essentially #Ladicek's comment:
[The behaviour] is intentional, but there are discussions it should be off by default. In any case, there's a configuration property to switch it off.
I was also able to locate the BuildExtension that does the magic: It is located inside io.quarkus.arc.deployment.devconsole.ArcDevConsoleProcessor.

How can I programmatically add a producer method to a CDI container during AfterBeanDiscovery?

I know how to add a Bean to a CDI container during AfterBeanDiscovery. My problem is that what I really need to do is the equivalent of adding a new producer method with the equivalent of a particularly qualified parameter.
That is, I'd like to somehow programmatically create several of these:
#Produces
#SomeQualifier("x")
private Foo makeFoo(#SomeQualifier("x") final FooMaker fm) {
return fm.makeFoo();
}
...where the domain over which SomeQualifier's value element ranges is known only at AfterBeanDiscovery time. In other words, some other portable extension has installed two FooMaker instances into the container: FooMaker-qualified-by-#SomeQualifier("x") and FooMaker-qualified-by-#SomeQualifier("y"). Now I need to do the equivalent of making two producer methods to "match" them.
Nonbinding is not an option; I want this resolution to take place at container startup, not at injection time.
I am aware of BeanManager's getProducerFactory method, but the dozens if not hundreds of lines of gymnastics I'd have to go through to add the right qualifier annotation on each AnnotatedParameter "reachable" from the AnnotatedMethod I'd have to create by hand (to avoid generics issues) make me think I'm way off the beaten path here.
Update: So in my extension, I have created a private static method that returns a Foo, and has a FooMaker parameter. I've wrapped this in a hand-tooled AnnotatedMethod that reports SomeQualifier("x") etc. in its getAnnotations() method, and also reports SomeQualifier("x") etc. from its AnnotatedParameter's getAnnotations() method. Then I got a ProducerFactory from the BeanManager and feed that into a new Bean that I create, where I use it to implement the create and destroy methods. Everything compiles and so forth just fine.
(However, Weld (in particular) blows up with this usage, which leads me to think that I'm doing Really Bad Thingsā„¢.)

What do I use to replace ToNullSafeString() removed from AutoMapper 3?

I have code using AutoMapper 3.2.1.0 that uses the method ToNullSafeString().
I upgraded the NUGet package to 4.1.1.0, and I can no longer find the method in their package.Does anyone know the recommended approach to replacing the function? Is there a new construct that is functionally equivalent? If so, I cannot figure what it is. Nor can I find any mention of why it was removed.
This question has actually been answered pretty well in a couple of comments below it. For completeness, here are a couple of actual implementations of solutions.
Short answer
Probably both the simplest and the best solution: Replace all instances of .ToNullSafeString() with ?.ToString(). This does the same, but uses functionality built into newer versions of .Net instead of relying on an external extension method.
Alternative answer
If you've got a bunch of calls to the ToNullSafeString() method from the earlier version Automapper, and for some reason or other you can't or don't want to go through all your code and edit it away right now, you can use this instead.
Add the following class to your project, and make sure it can be reached from any classes that previously called the Automapper-method. Those calls will then automatically point to this instead.
public static class NullSafeStringHelper
{
public static string ToNullSafeString(this object value)
{
return value?.ToString();
}
}

Trying to understand IOC and binding

I am very new to concept of IOC and I understand the fact that they help us resolve different classes in different contexts. Your calling class will just interact with Interface and Interface with decide which implementation to give you and it takes care of newing up the object.
Please do correct me if I am understanding is wrong because my question is based on that:
Now, I see this pattern very often in these projects:
private readonly IEmailService emailService;
private readonly ITemplateRenderer templateRenderer;
private readonly IHtmlToTextTransformer htmlToTextTransformer;
public TemplateEmailService(IEmailService emailService,
ITemplateRenderer templateRenderer,
IHtmlToTextTransformer htmlToTextTransformer)
{
this.emailService = emailService;
this.htmlToTextTransformer = htmlToTextTransformer;
this.templateRenderer = templateRenderer;
}
I understand that this helps using all the implementations of these classes without newing them up and also you don't have to decide WHICH implementaion to get, your IOC decides it for you, right?
but when I code like this, I do not even touch any IOC congiguration files. And again I am usin git for 2 days only but from all the tutorials that I have read, I was expecting my self to configure something which says "Resolve IParent to Child" class. But it works without me doing anything like it. Is it because there is only one implementaion of these interfaces? and If I do have more than one implementations then and then only I will have to configure resolved explicitly?
The code sample you have is a case of Constructor Injection.
In a traditional code, you would have a parameterless constructor, and in it you would "new-up" your objects like this:
IEmailService emailService = new EmailService();
So your code is explictly controlling which implementation gets assigned to the interface variable.
In IoC using constructor injection, control is inverted, meaning the container is "driving the bus" and is creating your TemplateEmailService object. When it is about to create it, the container looks at your constructor parameters (IEmailService , ITemplateRenderer , etc.) and feeds those objects to your class for use.
The IoC container can be configured so that interface A gets fulfilled by implementation B (or C) explicitly. Each one has a way to do it. Or it could do it by convention (IFoo fulfilled by Foo), or even attributes in classes, whatever.
So to answer your question-- you can explicitly define which implementations get used to fulfill certain interfaces. Got to read the IoC container docs for how to.
One more thing - "when you code like this", you technically don't have to be using an IoC container. In fact, your class should not have a direct reference to the container - it will maximize the reusability, and also allow easy testing. So you would wire-up interfaces to implementation classes elsewhere.

Code Contracts and Auto Generated Files

When I enabled code contracts on my WPF control project I ran into a problem with an auto generated file which was created at compile time (XamlNamespace.GeneratedInternalTypeHelper). Note, the generated file is called GeneratedInternalTypeHelper.g.cs and is not the same as the GeneratedInternalTypeHelper.g.i.cs which there are several obsolete blog posts about.
I'm not exactly sure what its purpose is, but I am assuming it is important for some internal reflection to resolve XAML. The problem is that it does not have code contracts, nor is the code contract system smart enough to recognize it as an auto generated file. This leads to a bunch of errors from the static checker.
I tried searching for a solution to this problem, but it seems like nobody is developing WPF controls and using code contracts. I did come across an interesting attribute, ContractVerificationAttribute, which takes a boolean value to set whether the assembly or class is to be verified. This allows you to decorate a class as not verified. Sadly the GeneratedInternalTypeHelper is regenerated with every compile, so it is not possible to exclude just this one class. The inverse scenario is possible though, decorate the assembly as not verified and then opt in for every class.
To mitigate the obvious hack I wanted to create a test that would at least verify that the exposed classes have code contract verification with a test like the following to ensure that own classes were at least being verified:
[Fact]
public void AllAssemblyTypesAreDecoratedWithContractVerificationTrue()
{
var assembly = typeof(someType).Assembly;
var exposedTypes = assembly.GetTypes().Where(t=>!string.IsNullOrWhiteSpace(t.Namespace) && t.Namespace.StartsWith("MyNamespace") && !t.Name.StartsWith("<>"));
var areAnyNotContractVerified = exposedTypes.Any(t =>
{
var verificationAttribute = t.GetCustomAttributes(typeof(ContractVerificationAttribute), true).OfType<ContractVerificationAttribute>();
return verificationAttribute.Any() && verificationAttribute.First().Value;
});
Assert.False(areAnyNotContractVerified);
}
As you can see it takes all classes in the controls assembly and finds the one from the company namespace which are not also auto generated anonymous types (<>WeirdClassName).
(I also need to exclude Resources and settings, but I hope you get the idea).
I'm not loving the solution since there are ways of avoiding contract verification, but currently it's the best I can come up with. If anyone has a better solution, please let me know.
So you can treat this class exactly like you would treat any other "3rd party" class or library. I'm sure certain assumptions would hold with the interaction with this generated class so at the interaction points, decorate your own code with Contract.Assume(result != null) or similar.
var result = new GennedClass().GetSomeValue();
Contract.Assume(result != null);
What this does is translate into an assertion that is checked at run time, but it allows the static analyzer to reason about the rest of the code that you do control.

Resources