Autofac is one of the most used dependency injection frameworks for .Net. It provides some advanced features compared to .Net Core standard DI library, like dynamic proxying and property injection.
## Install Autofac Integration
> All startup templates and samples are Autofac integrated. So, most of the time you don't need to manually install this package.
Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) nuget package to your project (for a multi-projects application, it's suggested to add to the executable/web project.)
````
Install-Package Volo.Abp.Autofac
````
Then add `AbpAutofacModule` dependency to your module:
```csharp
using Volo.Abp.Modularity;
using Volo.Abp.Autofac;
namespace MyCompany.MyProject
{
[DependsOn(typeof(AbpAutofacModule))]
public class MyModule : AbpModule
{
//...
}
}
```
Finally, configure `AbpApplicationCreationOptions` to replace default dependency injection services by Autofac. It depends on the application type.
### ASP.NET Core Application
Call `UseAutofac()` in the **Startup.cs** file as shown below:
````csharp
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.
ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.
### Modularity
> While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work. Startup templates come with Autofac installed. See [Autofac integration](Autofac-Integration.md) document for more information.
## Modularity
Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own seperate [module class](Module-Development-Basics.md). Example:
Since ABP is a modular framework, every module defines it's own services and registers via dependency injection in it's own seperate [module class](Module-Development-Basics.md). Example:
@ -16,7 +18,7 @@ public class BlogModule : AbpModule
}
}
````
````
### Conventional Registration
## Conventional Registration
ABP introduces conventional service registration. You need not do anything to register a service by convention. It's automatically done. If you want to disable it, you can set `SkipAutoServiceRegistration` to `true` by overriding the `PreConfigureServices` method.
ABP introduces conventional service registration. You need not do anything to register a service by convention. It's automatically done. If you want to disable it, you can set `SkipAutoServiceRegistration` to `true` by overriding the `PreConfigureServices` method.
@ -49,7 +51,7 @@ public class BlogModule : AbpModule
The section below explains the conventions and configurations.
The section below explains the conventions and configurations.
#### Inherently Registered Types
### Inherently Registered Types
Some specific types are registered to dependency injection by default. Examples:
Some specific types are registered to dependency injection by default. Examples:
@ -71,7 +73,7 @@ public class BlogPostAppService : ApplicationService
``BlogPostAppService`` is automatically registered with transient lifetime since it's derived from a known base class.
``BlogPostAppService`` is automatically registered with transient lifetime since it's derived from a known base class.
#### Dependency Interfaces
### Dependency Interfaces
If you implement these interfaces, your class is registered to dependency injection automatically:
If you implement these interfaces, your class is registered to dependency injection automatically:
@ -89,7 +91,7 @@ public class TaxCalculator : ITransientDependency
``TaxCalculator`` is automatically registered with a transient lifetime since it implements ``ITransientDependency``.
``TaxCalculator`` is automatically registered with a transient lifetime since it implements ``ITransientDependency``.
#### Dependency Attribute
### Dependency Attribute
Another way of configuring a service for dependency injection is to use ``DependencyAttribute``. It has the following properties:
Another way of configuring a service for dependency injection is to use ``DependencyAttribute``. It has the following properties:
@ -110,7 +112,7 @@ public class TaxCalculator
``Dependency`` attribute has a higher priority than other dependency interfaces if it defines the ``Lifetime`` property.
``Dependency`` attribute has a higher priority than other dependency interfaces if it defines the ``Lifetime`` property.
#### ExposeServices Attribute
### ExposeServices Attribute
``ExposeServicesAttribute`` is used to control which services are provided by the related class. Example:
``ExposeServicesAttribute`` is used to control which services are provided by the related class. Example:
@ -124,14 +126,14 @@ public class TaxCalculator: ICalculator, ITaxCalculator, ICanCalculate, ITransie
``TaxCalculator`` class only exposes ``ITaxCalculator`` interface. That means you can only inject ``ITaxCalculator``, but can not inject ``TaxCalculator`` or ``ICalculator`` in your application.
``TaxCalculator`` class only exposes ``ITaxCalculator`` interface. That means you can only inject ``ITaxCalculator``, but can not inject ``TaxCalculator`` or ``ICalculator`` in your application.
#### Exposed Services by Convention
### Exposed Services by Convention
If you do not specify which services to expose, ABP expose services by convention. So taking the ``TaxCalculator`` defined above:
If you do not specify which services to expose, ABP expose services by convention. So taking the ``TaxCalculator`` defined above:
* The class itself is exposed by default. That means you can inject it by ``TaxCalculator`` class.
* The class itself is exposed by default. That means you can inject it by ``TaxCalculator`` class.
* Default interfaces are exposed by default. Default interfaces are determined by naming convention. In this example, ``ICalculator`` and ``ITaxCalculator`` are default interfaces of ``TaxCalculator``, but ``ICanCalculate`` is not.
* Default interfaces are exposed by default. Default interfaces are determined by naming convention. In this example, ``ICalculator`` and ``ITaxCalculator`` are default interfaces of ``TaxCalculator``, but ``ICanCalculate`` is not.
#### Combining All Together
### Combining All Together
Combining attributes and interfaces is possible as long as it's meaningful.
Combining attributes and interfaces is possible as long as it's meaningful.
@ -144,7 +146,7 @@ public class TaxCalculator : ITaxCalculator, ITransientDependency
}
}
````
````
#### Manually Registering
### Manually Registering
In some cases, you may need to register a service to the `IServiceCollection` manually, especially if you need to use custom factory methods or singleton instances. In that case, you can directly add services just as [Microsoft documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) describes. Example:
In some cases, you may need to register a service to the `IServiceCollection` manually, especially if you need to use custom factory methods or singleton instances. In that case, you can directly add services just as [Microsoft documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) describes. Example:
@ -157,16 +159,18 @@ public class BlogModule : AbpModule
There are three common ways of using a service that has already been registered.
There are three common ways of using a service that has already been registered.
#### Contructor Injection
### Contructor Injection
This is the most common way of injecting a service into a class. For example:
This is the most common way of injecting a service into a class. For example:
@ -191,7 +195,7 @@ public class TaxAppService : ApplicationService
Constructor injection is preffered way of injecting dependencies to a class. In that way, the class can not be constructed unless all constructor-injected dependencies are provided. Thus, the class explicitly declares it's required services.
Constructor injection is preffered way of injecting dependencies to a class. In that way, the class can not be constructed unless all constructor-injected dependencies are provided. Thus, the class explicitly declares it's required services.
#### Property Injection
### Property Injection
Property injection is not supported by Microsoft Dependency Injection library. However, ABP can integrate with 3rd-party DI providers ([Autofac](https://autofac.org/), for example) to make property injection possible. Example:
Property injection is not supported by Microsoft Dependency Injection library. However, ABP can integrate with 3rd-party DI providers ([Autofac](https://autofac.org/), for example) to make property injection possible. Example:
@ -222,7 +226,7 @@ One restriction of property injection is that you cannot use the dependency in y
Property injection is also useful when you want to design a base class that has some common services injected by default. If you're going to use constructor injection, all derived classes should also inject depended services into their own constructors which makes development harder. However, be very careful using property injection for non-optional services as it makes it harder to clearly see the requirements of a class.
Property injection is also useful when you want to design a base class that has some common services injected by default. If you're going to use constructor injection, all derived classes should also inject depended services into their own constructors which makes development harder. However, be very careful using property injection for non-optional services as it makes it harder to clearly see the requirements of a class.
#### Resolve Service from IServiceProvider
### Resolve Service from IServiceProvider
You may want to resolve a service directly from ``IServiceProvider``. In that case, you can inject IServiceProvider into your class and use ``GetService`` method as shown below:
You may want to resolve a service directly from ``IServiceProvider``. In that case, you can inject IServiceProvider into your class and use ``GetService`` method as shown below:
@ -244,7 +248,7 @@ public class MyService : ITransientDependency
}
}
````
````
#### Releasing/Disposing Services
### Releasing/Disposing Services
If you used a constructor or property injection, you don't need to be concerned about releasing the service's resources. However, if you have resolved a service from ``IServiceProvider``, you might, in some cases, need to take care about releasing the service resources.
If you used a constructor or property injection, you don't need to be concerned about releasing the service's resources. However, if you have resolved a service from ``IServiceProvider``, you might, in some cases, need to take care about releasing the service resources.
@ -266,6 +270,12 @@ using (var scope = _serviceProvider.CreateScope())
Both services are released when the created scope is disposed (at the end of the using block).
Both services are released when the created scope is disposed (at the end of the using block).
### See Also
## 3rd-Party Providers
While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work.
Startup templates come with Autofac installed. See [Autofac integration](Autofac-Integration.md) document for more information.
## See Also
* [ASP.NET Core Dependency Injection Best Practices, Tips & Tricks](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96)
* [ASP.NET Core Dependency Injection Best Practices, Tips & Tricks](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96)
## Getting Started ABP With AspNet Core MVC Web Application
# Getting Started ABP With AspNet Core MVC Web Application
This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**.
This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**.
### Create A New Project
## Create A New Project
1. Create a new empty AspNet Core Web Application from Visual Studio:
1. Create a new empty AspNet Core Web Application from Visual Studio:
@ -14,7 +14,7 @@ This tutorial explains how to start ABP from scratch with minimal dependencies.
You could select another template, but I want to show it from a clear project.
You could select another template, but I want to show it from a clear project.
### Install Volo.Abp.AspNetCore.Mvc Package
## Install Volo.Abp.AspNetCore.Mvc Package
Volo.Abp.AspNetCore.Mvc is AspNet Core MVC integration package for ABP. So, install it to your project:
Volo.Abp.AspNetCore.Mvc is AspNet Core MVC integration package for ABP. So, install it to your project:
@ -22,7 +22,7 @@ Volo.Abp.AspNetCore.Mvc is AspNet Core MVC integration package for ABP. So, inst
Install-Package Volo.Abp.AspNetCore.Mvc
Install-Package Volo.Abp.AspNetCore.Mvc
````
````
### Create First ABP Module
## Create First ABP Module
ABP is a modular framework and it requires a **startup (root) module** class derived from ``AbpModule``:
ABP is a modular framework and it requires a **startup (root) module** class derived from ``AbpModule``:
@ -62,7 +62,7 @@ ABP packages define module classes and a module can depend on another module. In
Instead of Startup class, we are configuring ASP.NET Core pipeline in this module class.
Instead of Startup class, we are configuring ASP.NET Core pipeline in this module class.
### The Startup Class
## The Startup Class
Next step is to modify Startup class to integrate to ABP module system:
Next step is to modify Startup class to integrate to ABP module system:
@ -95,7 +95,7 @@ Changed ``ConfigureServices`` method to return ``IServiceProvider`` instead of `
``app.InitializeApplication()`` call in ``Configure`` method initializes and starts the application.
``app.InitializeApplication()`` call in ``Configure`` method initializes and starts the application.
### Hello World!
## Hello World!
The application above does nothing. Let's create an MVC controller does something:
The application above does nothing. Let's create an MVC controller does something:
@ -120,13 +120,13 @@ If you run the application, you will see a "Hello World!" message on the page.
Derived ``HomeController`` from ``AbpController`` instead of standard ``Controller`` class. This is not required, but ``AbpController`` class has useful base properties and methods to make your development easier.
Derived ``HomeController`` from ``AbpController`` instead of standard ``Controller`` class. This is not required, but ``AbpController`` class has useful base properties and methods to make your development easier.
### Using Autofac as the Dependency Injection Framework
## Using Autofac as the Dependency Injection Framework
While AspNet Core's Dependency Injection (DI) system is fine for basic requirements, Autofac provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features.
While AspNet Core's Dependency Injection (DI) system is fine for basic requirements, Autofac provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features.
Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy.
Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy.
Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication).
Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication).
This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**.
This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with a **[startup template](https://abp.io/Templates)**.
### Create A New Project
## Create A New Project
Create a new Regular .Net Core Console Application from Visual Studio:
Create a new Regular .Net Core Console Application from Visual Studio:
Volo.Abp.Core is the core nuget package to create ABP based applications. So, install it to your project:
Volo.Abp.Core is the core nuget package to create ABP based applications. So, install it to your project:
@ -16,7 +16,7 @@ Volo.Abp.Core is the core nuget package to create ABP based applications. So, in
Install-Package Volo.Abp.Core
Install-Package Volo.Abp.Core
````
````
### Create First ABP Module
## Create First ABP Module
ABP is a modular framework and it requires a **startup (root) module** class derived from ``AbpModule``:
ABP is a modular framework and it requires a **startup (root) module** class derived from ``AbpModule``:
@ -35,7 +35,7 @@ namespace AbpConsoleDemo
``AppModule`` is a good name for the startup module for an application.
``AppModule`` is a good name for the startup module for an application.
### Initialize The Application
## Initialize The Application
The next step is to bootstrap the application using the startup module created above:
The next step is to bootstrap the application using the startup module created above:
@ -64,7 +64,7 @@ namespace AbpConsoleDemo
``AbpApplicationFactory`` is used to create the application and load all modules taking ``AppModule`` as the startup module. ``Initialize()`` method starts the application.
``AbpApplicationFactory`` is used to create the application and load all modules taking ``AppModule`` as the startup module. ``Initialize()`` method starts the application.
### Hello World!
## Hello World!
The application above does nothing. Let's create a service that does something:
The application above does nothing. Let's create a service that does something:
@ -119,6 +119,63 @@ namespace AbpConsoleDemo
While it's enough for this simple code example, it's always suggested to create scopes in case of directly resolving dependencies from ``IServiceProvider`` (see the [Dependency Injection documentation](Dependency-Injection.md)).
While it's enough for this simple code example, it's always suggested to create scopes in case of directly resolving dependencies from ``IServiceProvider`` (see the [Dependency Injection documentation](Dependency-Injection.md)).
### Source Code
## Using Autofac as the Dependency Injection Framework
While AspNet Core's Dependency Injection (DI) system is fine for basic requirements, Autofac provides advanced features like Property Injection and Method Interception which are required by ABP to perform advanced application framework features.
Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy.
Console.WriteLine("Press ENTER to stop application...");
Console.ReadLine();
}
}
}
}
```
Just called `options.UseAutofac()` method in the `AbpApplicationFactory.Create` options.
## Source Code
Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication).
Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication).