Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No visual cues with SimpleInjector #42

Open
lennartb- opened this issue Aug 5, 2019 · 6 comments
Open

No visual cues with SimpleInjector #42

lennartb- opened this issue Aug 5, 2019 · 6 comments
Assignees

Comments

@lennartb-
Copy link

lennartb- commented Aug 5, 2019

R# 2019.1.3
Agent Mulder 2019.1.0
VS 16.2.0
SimpleInjector 4.6.0

Hi,

I'm new to this plugin and I can't see any visual cues at all, I also see no configuration options or indication that the plugin works at all (only that it's installed in R#s plugin manager). We use SimpleInjector to register our command interface:

var commandType = typeof(IOurCommand<>);

Container.Register(commandType, commandType.Assembly);

Container.RegisterDecorator(commandType, typeof(TransactionCommandAspect<>));

And a sample aspect:

public class TransactionCommandAspect<TCommand> : IOurCommand<TCommand> {...}

and sample command:

public class HelpCommand : IOurCommand<OurModel> {...}

I should at least see "Navigate to -> Registered Components" on our interface, right? Am I missing some configuration I need to do before?

@mareklinka
Copy link

Hi @lennartb- and thanks for the report. I'll try and replicate the behavior and see if if I can figure out what's wrong.

@mareklinka mareklinka self-assigned this Aug 5, 2019
@lennartb-
Copy link
Author

lennartb- commented Aug 5, 2019

Thanks, let me know if you need any more info!

@mareklinka
Copy link

After a (very) brief look the problem might be caused by API changes in the SimpleInjector library. The SimpleInjector support in Mulder is rather old and has not been updated in a few years. I will try and have a look if we can update it and make your scenario supported.

@mareklinka
Copy link

So I took a deeper look at how the SimpleInjector support is implemented and I don't have the best of news. The Mulder-supported SI version is majorly outdated and the API changed quite a lot. That most likely means our best course of action would be to rewrite the SI support from scratch, for which we don't have the capacity right now.

More technically, the SI API converged to using a single Register method for a lot of cases originally covered by separate methods. This means we would have to update the logic for this Register method and majorly improve type resolution of its parameters.

There is some precedent with the introduction of the ASP.NET Core DI support that did a lot for type resolution improvements but this is beyond the scope for a simple fix. I'll keep this issue open to keep track and maybe we can spare some capacity for this later but I'm afraid we won't be able to solve this for you right now.

I'm sorry to deliver this disappointing news. On the other hand, we would be glad to provide help and accept a pull requested if you wanted to try your hand at fixing the problem yourself.

@lennartb-
Copy link
Author

Thanks for looking into this. To you have a guesstimate on how complicated that would be for someone (i.e. me) not familiar with the Mulder code base to implement? I hade a quick look into the AgentMulder.Containers.SimpleInjector.Patterns namespace and it looks like "just" a couple of classes that would need to be adapted and/or pruned to support the single Register method.

@mareklinka
Copy link

I'd say it's not too difficult but it's not straightforward either. Basically, you will need to be at least a little familiar with two things:

  1. ReSharper's structural search - these are the patterns that you can use to detect if something looks like a registration. This gives you a piece of code that you need to analyze to determine what is being registered.
  2. ReSharper's abstract syntax trees of C# code - from step 1 you will get a pointer to an AST element describing your matched registration. This is most often a method call. Now you would need to dive deeper into the method call and figure out the parameters, their types etc. This should eventually give you enough information to say "type X is being registered here as service type Y". This then gets reported back to Mulder.

Step 1 is usually done in those classes under /Patterns. Some containers have a lot of patterns, some have only a few, depending on the container's API. Step 2 is usually done in the base class of those patterns (mostly because the analysis is usually similar regardless of the actual pattern). For SimpleInjector, it's the RegisterWithService class.

However, the RegisterWithService class is rather old and the analysis is rather simple there. You can take a look at AspNetCorePatternBase (a base for the ASP.NET Core DI patterns) that performs a much deeper and more precise analysis of the AST. There is also some inherent non-determinism in trying to figure out the registration types because there are cases when pure static analysis isn't sufficient. E.g. if you register a service using a factory method, the factory method might contain some code that makes it impossible to determine what will be the actual implementation type (e.g. if today is Monday, return type X, else return type Y. A stupid example for sure but should give you the right idea).

And of course then there are tests and the test harness is rather convoluted (however, it mostly "just works" if you prepare your test data right).

So, bottom line, this should give you some idea of what is involved. Given enough time and a little determination, I'm sure you will be able to figure this stuff out (and we are here to help, of course). So if you want to try it out, awesome! If not, I completely understand, it might look like a major effort at a closer look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants