I Have a spring boot application with following config.
#Configuration
#EnableWebMvc
#ComponentScan({ "com.xxx.mypackages" })
public class MyWebAppConfiguration extends WebMvcConfigurerAdapter {
}
In my project I have some web services and spring controllers. I want swagger to be enabled only in my web service classes. Currently, it generates documentation for both rest and controller classes. How can I customize that?
I'm using following dependency in gradle.
compile "com.mangofactory:swagger-springmvc:1.0.2"
If you look at the 1.0.2 documentation you'll find that SwaggerSpringMvcPlugin has a includePatterns method. This method takes a regular expression of the paths to include. For e.g. if you had an path prefix for the rest endpoints like this /rest/some-resource.... you could include a pattern, something like the snippet shown below
#Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
//... more config goes here
//regex to identify your rest services path
.includePatterns(".*rest.*");
}
Also it would be useful to know that we're going to be releasing 2.0 shortly with support for swagger spec 2.0. That might be something to consider as well.
Related
I am confused on how to use a Razor Class Library that requires injected objects.
I created a new razor class library project.
There is no program.cs file and hence no WebAssemblyHostBuilder to add services to?
How do I inject dependencies into the components?
A library is simply that. It's not an application. You load the DI objects in the application project. You can write extension classes in your library as a wrapper to load all the necessary objects. builder.Services.AddServerSideBlazor() is just such an extension.
Here's an example extension method for the Weather Forecast.
public static class ServiceCollectionExtensions
{
public static void AddWeatherServices(this IServiceCollection services)
{
services.AddSingleton<WeatherForecastService>();
}
}
And use it in the application startup:
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddWeatherServices();
You inject the services into your components as normal. If you use a component in an application and the necessary services aren't loaded the page on which the component is being used will throw an error.
I am writing integration testing and came across a requirement to disable to calling adding swagger function in startup. I am using the same startup class without customizing it.
Please suggest some solution to get rid of swagger and it's inner function implementation like adding authentication.
Thanks.
1) You can use a custom startup class for your Integration Testing project. There you can leave out the code to use swagger.
(or)
2) You can add a key in appsettings.json to identify a test run.
In Startup.cs - ConfigureServices() and Configure() methods, you can check the key, and if it is test run, you can avoid calling Swagger code.
I have the following structure of my net core solution.
API - web api
Interfaces - class library
Implementation - class library
Models - class library
In the API startup.cs, I have registered the service like so:
services.AddHttpClient();
I have a class as such in the Implementation Project
using System.Net.Http;
public IHttpClientFactory ihttpClientFactory;
public class FooImplementation: IFoo {
public void someFooMethod(){
// here call client to fetch data from api
// process this data
}
}
I wanted to inject a IHttpClientFactory into this, however it is complaining that it cannot be found. How can I resolve this error? and Also, Is this the correct approach to pass IHttpClientFactory into this class library based on the project structure?
You do have to check the documentation of IHttpClientFactory carefully, which says,
Namespace: System.Net.Http
Assembly: Microsoft.Extensions.Http.dll
That's the hint on which NuGet package to use, so you should add a package reference to Microsoft.Extensions.Http.
I read the article yesterday: https://igor.io/2012/11/09/scaling-silex.html
And another one http://davedevelopment.co.uk/2012/10/03/Silex-Controllers-As-Services.html
So a conceptual question rised in my head:
Currently I do have a lot of controllers in separate classes. I overwrite controller_resolver to create a controller class instance and inject $app into contoller's constructor.
I define routes like this $app->get('/hello', 'HelloController::indexAction') <- my controller resolver will create new HelloController($app); - so far so good.
But to be honest it became a ServiceLocator pattern, not a DependencyInjection, because I do inject whe whole $app which looks like ServiceLocator usage.
Now I am in doubt: should I leave it as is (because it works well) or try "controllers as services" to inject only those sevices on which my controller really depends on? May be my SeviceLocator approach will hit me some day? (people say that DI is better for tests).
I have also looked into Symfony Framework Bundle: class Controller extends abstract class ContainerAware which also have the whole $container injected! ServiceLocator approach in full stack framework?
Any recomendation? Pros/cons?
The symfony2 full-stack framework
The framework uses the Dependency Injection pattern and not the Service Locator pattern.
All controllers aren't services by default. The ContainerAware class includes methods to get access to the service container, so you can call Services inside the Controller.
If you are going to use a Controller as a Service you need to remove the Controller extend. All dependencies you want to use inside the controller needs to be injected by the Service Container.
Read more about this in a blogpost by richard miller, one of the core contributors of Symfony2.
The Silex micro-framework
The Silex micro-framework provides the bare bones of a framework, it's up to you how the architecture looks and which patterns you use.
The Silex documentation uses Controllers that aren't Services. It injects the complete Service Container inside very Controller:
$app->post('/post/{id}-{slug}', function($id, $slug) use ($app) {
// ...
});
If you want to use controllers as service, you should only inject the services you want to use inside the controller.
EDIT: The Controller::action syntax refers also to a Controller that isn't a Service. The Controller:action notation is used to refer to Controllers as Services.
There's lot's of personal preference involved here. What you've done already is a good (enough) step to organising your code base. Some people like myself take things a step further and move our controllers to the container, rather than injecting it in to some kind of BaseController. This happens in both Silex and the full stack Symfony framework.
My advice would be to leave everything you have as is, then try defining your next controller as a service, by practising BDD.
For example, the behaviour of a UserController view action:
It should retrieve the user from a database
It should render the user with a template
Not once does it mention retrieving the database or the template renderer from a container. I'm comfortable not injecting the container, so I'll only inject what I'm led to believe I need by BDD.
When using Unity 2.0 for dependency injection within a web application, it appears that user controls, pages, etc will all need make explicit calls to retrieve the container and "fetch" the dependencies … so using the annotations like [dependency] won't offer any value. This is likely since the location of the container (application context, http context cache, etc.) is unknown in the web configuration.
Since Unity itself provides method interception, isn't there a way to "tell" unity how to fetch the container correctly when you build your own web application? Rather than having to create base classes for page, etc.?
The problem is that the WebForms Pages and Controls are not set up to allow for construction by dependency injection, so Unity never gets invoked at all unless the class invokes Unity itself. I've found the best pattern in these cases is to invoke the DI framework in the constructor via a Service Locator and then use annotations to mark dependency properties. Something like this:
public MyPage()
{
// Injector is a wrapper class so you can change the underlying DI framework
// later if necessary.
Injector.Inject(this);
}
[Dependency]
public SomeService MyService {get;set;}