Skip to content

Commit

Permalink
Resolved #486: AutoFac integration document.
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalkan committed Dec 18, 2018
1 parent ed51dea commit 7f6552f
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 38 deletions.
85 changes: 83 additions & 2 deletions docs/en/Autofac-Integration.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,84 @@
## Autofac Integration
# Autofac Integration

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)
{
services.AddApplication<MyWebModule>(options =>
{
//Integrate Autofac!
options.UseAutofac();
});

return services.BuildServiceProviderFromFactory();
}

public void Configure(IApplicationBuilder app)
{
app.InitializeApplication();
}
}
````

### Console Application

Call `UseAutofac()` method in the `AbpApplicationFactory.Create` options as shown below:

````csharp
using System;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;

namespace AbpConsoleDemo
{
class Program
{
static void Main(string[] args)
{
using (var application = AbpApplicationFactory.Create<AppModule>(options =>
{
options.UseAutofac(); //Autofac integration
}))
{
//...
}
}
}
}
````

TODO
44 changes: 27 additions & 17 deletions docs/en/Dependency-Injection.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
## Dependency Injection
# Dependency Injection

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:

Expand All @@ -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.

Expand Down Expand Up @@ -49,7 +51,7 @@ public class BlogModule : AbpModule

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:

Expand All @@ -71,7 +73,7 @@ public class BlogPostAppService : ApplicationService

``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:

Expand All @@ -89,7 +91,7 @@ public class TaxCalculator : 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:

Expand All @@ -110,7 +112,7 @@ public class TaxCalculator

``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:

Expand All @@ -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.

#### 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:

* 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.

#### Combining All Together
### Combining All Together

Combining attributes and interfaces is possible as long as it's meaningful.

Expand All @@ -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:

Expand All @@ -157,16 +159,18 @@ public class BlogModule : AbpModule
context.Services.AddSingleton<TaxCalculator>(new TaxCalculator(taxRatio: 0.18));

//Register a factory method that resolves from IServiceProvider
context.Services.AddScoped<ITaxCalculator>(sp => sp.GetRequiredService<TaxCalculator>());
context.Services.AddScoped<ITaxCalculator>(
sp => sp.GetRequiredService<TaxCalculator>()
);
}
}
````

### Injecting Dependencies
## Injecting Dependencies

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:

Expand All @@ -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.

#### 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:

Expand Down Expand Up @@ -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.

#### 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:

Expand All @@ -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.

Expand All @@ -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).

### 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)
18 changes: 9 additions & 9 deletions docs/en/Getting-Started-AspNetCore-Application.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## 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)**.

### Create A New Project
## Create A New Project

1. Create a new empty AspNet Core Web Application from Visual Studio:

Expand All @@ -14,15 +14,15 @@ 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.

### 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:

````
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``:

Expand Down Expand Up @@ -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.

### The Startup Class
## The Startup Class

Next step is to modify Startup class to integrate to ABP module system:

Expand Down Expand Up @@ -95,7 +95,7 @@ Changed ``ConfigureServices`` method to return ``IServiceProvider`` instead of `

``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:

Expand All @@ -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.

### 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.

Replacing AspNet Core's DI system by Autofac and integrating to ABP is pretty easy.

1. Install Volo.Abp.Autofac package
1. Install [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) package

````
Install-Package Volo.Abp.Autofac
Expand All @@ -152,6 +152,6 @@ services.AddApplication<AppModule>(options =>
});
````

### Source Code
## Source Code

Get source code of the sample project created in this tutorial from [here](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication).
Loading

0 comments on commit 7f6552f

Please sign in to comment.