Chủ đề của Advanced Cross-Platform Application Programming With .NET - Lập trình ứng dụng đa nền tảng nâng cao với .NET

PRN222 - Chương 3: Dependency Injection và IoC

Dependency Injection và Inversion of Control trong PRN222: vòng đời service AddSingleton, AddScoped, AddTransient và cách chọn đúng vòng đời. Nội dung chương còn gồm constructor injection, property injection cho phụ thuộc tuỳ chọn, method injection, ServiceCollection, IServiceProvider, container built-in Microsoft.Extensions.DependencyInjection, cùng nguyên lý SOLID với Dependency Inversion và Open Closed. Học xong chương này, người học đăng ký và tiêm được phụ thuộc đúng vòng đời cho một ứng dụng ASP.NET Core.

Xem danh sách câu hỏi19 câu hỏi100% có giải thích

Bắt đầu bằng Chế độ học nếu bạn muốn đáp án và giải thích hiện ngay sau mỗi câu — không bấm giờ, dừng lúc nào cũng được. Chọn Thi thử khi muốn biết mình đang ở đâu: có bấm giờ, chấm điểm ở cuối, và giải thích chỉ mở sau khi nộp.

Học ngân hàng câu hỏi của chủ đề

Luyện tập theo chủ đề này

19Câu hỏi hiện có

Câu hỏi của chủ đề

19/19 câuHết danh sách
1Given the code:4 lựa chọncó codeDễ88% trả lời đúng
Đề bài
builder.Services.AddScoped<IOrderService, OrderService>();

How will OrderService behave?

ASame instance for the entire application
BNew instance for each HTTP request
CNew instance every time injected
DThread-local instance
Lời giải
Khi sử dụng phương thức Scoped trong Dependency Injection của .NET, OrderService sẽ được tạo mới cho mỗi yêu cầu HTTP. Điều này có nghĩa là mỗi lần OrderService được yêu cầu, một phiên bản mới sẽ được tạo và sử dụng cho đến khi yêu cầu đó kết thúc. Điều này giúp đảm bảo rằng mỗi yêu cầu HTTP có một phiên bản riêng biệt của OrderService, tránh được các vấn đề liên quan đến việc chia sẻ trạng thái giữa các yêu cầu khác nhau.
Mở trang câu hỏi này →
2What does this code do?4 lựa chọncó codeDễ100% trả lời đúng
Đề bài
services.AddTransient<ILogger, ConsoleLogger>();
ARegisters ILogger so that each request gets a new ConsoleLogger instance
BRegisters ILogger as a singleton
CRegisters ConsoleLogger directly without abstraction
DThrows an error since ILogger is abstract
Lời giải
Trong mã code này, đoạn địch vụ AddTransient được sử dụng để đăng ký một dịch vụ ILogger với một thực thể ConsoleLogger cụ thể. Đoạn địch vụ AddTransient cho phép mỗi yêu cầu nhận được một phiên bản mới của ConsoleLogger. Điều này có nghĩa là mỗi lần yêu cầu được xử lý, một phiên bản mới của ConsoleLogger sẽ được tạo ra và sử dụng, sau đó bị hủy bỏ khi yêu cầu được hoàn thành. Điều này giúp đảm bảo rằng mỗi yêu cầu nhận được một phiên bản mới và độc lập của ConsoleLogger, mà không bị ảnh hưởng bởi các yêu cầu khác.
Mở trang câu hỏi này →
AA global application configuration.
BA request-specific database context in a web application.
CA stateless utility service.
DA single instance of a logger.
Lời giải
Một dịch vụ có thời gian sống đượcScoped là một dịch vụ có thể được tạo mới và hủy bỏ trong mỗi yêu cầu. Ví dụ về một tình huống nơi một dịch vụ có thời gian sống đượcScoped sẽ phù hợp là khi bạn cần một đối tượng cơ sở dữ liệu cụ thể cho mỗi yêu cầu trong một ứng dụng web. Điều này có thể giúp ngăn chặn các vấn đề về đồng bộ hóa và đảm bảo rằng mỗi yêu cầu có một đối tượng cơ sở dữ liệu độc lập.
Mở trang câu hỏi này →
4What is the main goal of Inversion of Control (IoC)?4 lựa chọnDễ100% trả lời đúng
ATo increase performance
BTo invert object creation responsibility
CTo remove polymorphism
DTo disable inheritance
Lời giải
Inversion of Control (IoC) là một nguyên tắc thiết kế phần mềm quan trọng trong lập trình. Mục tiêu chính của IoC là đảo ngược trách nhiệm tạo đối tượng. Thay vì các đối tượng phụ thuộc vào các đối tượng khác để tạo ra, IoC cho phép các đối tượng được tạo ra và quản lý bởi một hệ thống trung tâm. Điều này giúp giảm sự phức tạp và tăng tính linh hoạt của mã nguồn. IoC cũng cho phép dễ dàng thay đổi hoặc thay thế các đối tượng mà không ảnh hưởng đến các đối tượng khác. Nói cách khác, IoC giúp giảm sự phụ thuộc giữa các đối tượng và tăng cường khả năng mở rộng của hệ thống.
Mở trang câu hỏi này →
5What is "Constructor Injection"?4 lựa chọnDễ100% trả lời đúng
AInjecting dependencies via properties.
BInjecting dependencies via method parameters.
CInjecting dependencies through a class's constructor.
DInjecting dependencies at runtime.
Lời giải
Constructor Injection là một kỹ thuật trong lập trình hướng đối tượng, giúp tạo ra các đối tượng có thể dễ dàng sử dụng và thử nghiệm. Nó liên quan đến việc cung cấp các phụ thuộc (dependencies) cho một lớp (class) thông qua phương thức (method) khởi tạo (constructor) của nó. Điều này cho phép các phụ thuộc được tạo ra và cung cấp cho lớp một cách tự động, giảm thiểu sự phức tạp và tăng cường tính linh hoạt của mã.
Mở trang câu hỏi này →
6Dependency Inversion Principle states:4 lựa chọnDễ100% trả lời đúng
AHigh-level modules should depend on low-level modules
BBoth high-level and low-level modules should depend on abstractions
CAbstractions should depend on details
DInterfaces should depend on classes
Lời giải
Sự nguyên tắc phụ thuộc ngược (Dependency Inversion Principle) là một nguyên tắc thiết kế quan trọng trong lập trình hướng đối tượng. Nó cho rằng các mô-đun cao cấp (high-level modules) và mô-đun thấp cấp (low-level modules) nên phụ thuộc vào các abstraction (tính trừu tượng) chứ không phải vào nhau. Điều này có nghĩa là thay vì các mô-đun cao cấp phụ thuộc vào các mô-đun thấp cấp cụ thể, chúng nên phụ thuộc vào các interface hoặc abstraction chung. Điều này giúp giảm sự phụ thuộc giữa các mô-đun và tăng tính linh hoạt, dễ dàng thay đổi và mở rộng hệ thống.
Mở trang câu hỏi này →
7What is the purpose of the IServiceProvider interface?4 lựa chọnDễ100% trả lời đúng
ATo define database connections.
BTo resolve registered services from the DI container.
CTo define network protocols.
DTo define user interface elements.
Lời giải
Lớp IServiceProvider là một giao diện quan trọng trong mô hình Dependency Injection (DI). Mục đích chính của giao diện này là cung cấp một cách thức để giải quyết các dịch vụ đã được đăng ký trong container DI. Khi một ứng dụng sử dụng mô hình DI, nó sẽ đăng ký các dịch vụ cần thiết vào container. Sau đó, khi ứng dụng cần sử dụng một dịch vụ, nó sẽ sử dụng giao diện IServiceProvider để giải quyết dịch vụ đó từ container. Điều này giúp ứng dụng trở nên linh hoạt và dễ dàng quản lý các dịch vụ của mình.
Mở trang câu hỏi này →
8Which of the following is NOT a type of Dependency Injection?4 lựa chọnDễ71% trả lời đúng
AConstructor Injection
BSetter Injection
CMethod Injection
DDatabase Injection
Lời giải
Tùy chọn không phải là loại Dependency Injection là Database Injection. Dependency Injection là một kỹ thuật lập trình giúp giảm sự phụ thuộc giữa các lớp và các thành phần trong một ứng dụng. Có ba loại Dependency Injection chính: Constructor Injection, Setter Injection và Method Injection. Constructor Injection là kỹ thuật truyền đối tượng phụ thuộc vào một lớp thông qua phương thức constructor của lớp đó. Điều này giúp giảm sự phụ thuộc giữa các lớp và tăng tính linh hoạt của ứng dụng. Setter Injection là kỹ thuật truyền đối tượng phụ thuộc vào một lớp thông qua phương thức setter của lớp đó. Điều này giúp giảm sự phụ thuộc giữa các lớp và tăng tính linh hoạt của ứng dụng. Method Injection là kỹ thuật truyền đối tượng phụ thuộc vào một lớp thông qua phương thức khác của lớp đó. Điều này giúp giảm sự phụ thuộc giữa các lớp và tăng tính linh hoạt của ứng dụng. Database Injection là một kỹ thuật tấn công bảo mật, không phải là một loại Dependency Injection. Nó liên quan đến việc sử dụng mã SQL để tấn công các ứng dụng web và lấy được dữ liệu nhạy cảm.
Mở trang câu hỏi này →
9What is the main purpose of Dependency Injection?4 lựa chọnTrung bình67% trả lời đúng
ATo create dependencies inside a class
BTo remove hard-coded dependencies
CTo increase code complexity
DTo avoid using interfaces
Lời giải
Dependency Injection (DI) là một kỹ thuật lập trình giúp giảm sự phụ thuộc giữa các lớp hoặc mô-đun trong một ứng dụng. Mục đích chính của DI là loại bỏ các phụ thuộc cứng (hard-coded dependencies) giữa các lớp, giúp tăng tính linh hoạt và dễ dàng bảo trì của ứng dụng. Khi sử dụng DI, bạn có thể dễ dàng thay thế các phụ thuộc bằng các implementation khác nhau mà không cần phải thay đổi mã nguồn của lớp sử dụng phụ thuộc. Điều này giúp giảm sự phức tạp và tăng tính tái sử dụng của mã nguồn. Ngoài ra, DI cũng giúp giảm sự phụ thuộc vào các framework hoặc thư viện cụ thể, giúp ứng dụng trở nên dễ dàng di chuyển sang các nền tảng khác nhau.
Mở trang câu hỏi này →
AInterface Segregation
BOpen/Closed Principle
CDependency Inversion
DLiskov Substitution
Lời giải
SOLID là một nhóm nguyên tắc thiết kế giúp đảm bảo tính mở rộng và bảo trì của mã nguồn. Trong đó, nguyên tắc Open/Closed Principle (OCP) cho rằng một lớp nên được mở rộng, nhưng không được sửa đổi khi có yêu cầu mới. Nếu một lớp phải được sửa đổi liên tục khi có yêu cầu mới, điều đó có nghĩa là lớp đó không tuân thủ nguyên tắc OCP. Điều này dẫn đến việc lớp đó không có khả năng mở rộng và bảo trì, khiến cho việc thêm mới yêu cầu trở nên khó khăn và phức tạp.
Mở trang câu hỏi này →
11Which DI pattern provides optional dependencies?4 lựa chọnTrung bình67% trả lời đúng
AConstructor Injection
BProperty Injection
CMethod Injection
DAmbient Context
Lời giải
Mẫu thiết kế DI (Dependency Injection) cung cấp tùy chọn phụ thuộc là Property Injection. Trong Property Injection, phụ thuộc được cung cấp cho đối tượng thông qua thuộc tính của nó. Điều này cho phép phụ thuộc được cung cấp một cách linh hoạt và có thể được thay đổi trong thời gian chạy. Điều này đặc biệt hữu ích khi cần phải cung cấp phụ thuộc tùy thuộc vào tình huống cụ thể hoặc môi trường cụ thể. Ví dụ, một đối tượng có thể được thiết kế để sử dụng một cơ sở dữ liệu cụ thể trong môi trường sản xuất nhưng sử dụng một cơ sở dữ liệu khác trong môi trường thử nghiệm. Property Injection cho phép thực hiện điều này một cách dễ dàng và linh hoạt.
Mở trang câu hỏi này →
AA new instance of FileLogger is created each time
BThe same FileLogger instance is shared across the application
CA new FileLogger instance is created per request
DThe instance is disposed immediately
Lời giải
Khi dịch vụ AddSingleton được sử dụng, nó sẽ tạo một đối tượng FileLogger duy nhất và chia sẻ nó cho tất cả các lớp trong ứng dụng. Điều này có nghĩa là khi ILogger được inject vào các lớp khác nhau, tất cả chúng sẽ sử dụng cùng một đối tượng FileLogger. Điều này giúp giảm thiểu việc tạo và quản lý các đối tượng, đồng thời cải thiện hiệu suất của ứng dụng. Tuy nhiên, cần lưu ý rằng AddSingleton không đảm bảo rằng đối tượng sẽ tồn tại mãi mãi, mà chỉ là một đối tượng được tạo và chia sẻ trong suốt vòng đời của ứng dụng.
Mở trang câu hỏi này →
13Consider this C# code:4 lựa chọncó codeDễ100% trả lời đúng
Đề bài
services.AddTransient<IEmailService, SmtpEmailService>();

What happens when IEmailService is requested multiple times?

AOnly one instance is ever created
BA new instance is created each time it's requested
COne instance per request is created
DThe DI container throws an exception
Lời giải
Khi bạn sử dụng phương thức AddTransient trong Dependency Injection (DI) của C#, nó sẽ tạo ra một đối tượng thực thi IEmailService (SmtpEmailService) mỗi khi bạn yêu cầu nó. Điều này có nghĩa là mỗi lần bạn yêu cầu IEmailService, một đối tượng mới sẽ được tạo ra. Nếu bạn yêu cầu IEmailService nhiều lần, sẽ có nhiều đối tượng SmtpEmailService được tạo ra. Điều này khác với các phương thức khác như AddScoped hoặc AddSingleton, nơi đối tượng sẽ được tạo ra một lần và sử dụng nhiều lần.
Mở trang câu hỏi này →
14What is "Property Injection"?4 lựa chọnDễ71% trả lời đúng
AInjecting dependencies via constructors.
BInjecting dependencies via method parameters.
CInjecting dependencies by setting public properties.
DInjecting dependencies at compile time.
Lời giải
Property Injection là một kỹ thuật trong lập trình hướng đối tượng, cho phép bạn cung cấp các phụ thuộc (dependencies) cho một đối tượng bằng cách thiết lập các thuộc tính công khai của nó. Điều này cho phép bạn tách rời việc tạo ra phụ thuộc khỏi việc tạo ra đối tượng chính, giúp tăng tính linh hoạt và dễ dàng bảo trì trong thiết kế hệ thống. Ví dụ, khi bạn muốn tạo một đối tượng User, bạn có thể sử dụng Property Injection để cung cấp cho nó một đối tượng Database để truy cập dữ liệu. Điều này giúp giảm thiểu sự phụ thuộc giữa các lớp và tăng cường khả năng tái sử dụng.
Mở trang câu hỏi này →
15Which built-in container does .NET Core provide for DI?4 lựa chọnDễ100% trả lời đúng
AAutofac
BUnity
CMicrosoft.Extensions.DependencyInjection
DNinject
Lời giải
Trong .NET Core, có một số container được sử dụng để quản lý Dependency Injection (DI). Tuy nhiên, container được tích hợp sẵn và được khuyến nghị sử dụng là Microsoft.Extensions.DependencyInjection. Nó cung cấp các tính năng cơ bản để quản lý các đối tượng và dịch vụ trong ứng dụng. Container này cho phép bạn dễ dàng thêm, xóa và quản lý các dịch vụ mà không cần phải viết mã phức tạp. Ngoài ra, nó cũng hỗ trợ các tính năng như đăng ký dịch vụ, tạo đối tượng và quản lý vòng đời của các đối tượng. Sử dụng Microsoft.Extensions.DependencyInjection giúp bạn có thể tập trung vào việc phát triển ứng dụng mà không cần phải lo lắng về việc quản lý các dịch vụ và đối tượng.
Mở trang câu hỏi này →
ASingleton
BScoped
CTransient
DIsolated
Lời giải
Đáp án đúng: "Transient". Trong DI của ASP.NET Core có ba vòng đời. Transient tạo một thể hiện MỚI mỗi lần được yêu cầu, phù hợp với dịch vụ nhẹ, không giữ trạng thái. Scoped tạo một thể hiện cho mỗi phạm vi, trong ứng dụng web là mỗi HTTP request - điển hình là DbContext. Singleton chỉ tạo một thể hiện duy nhất dùng suốt vòng đời ứng dụng. "Isolated" không phải một vòng đời trong hệ thống DI tích hợp sẵn của .NET.
Mở trang câu hỏi này →
17What is Inversion of Control (IoC)?4 lựa chọn
AA programming paradigm where the control flow of a program is inverted compared to traditional procedural programming.
BA method for managing memory allocation.
CA technique for optimizing network traffic.
DA way to encrypt data.
Lời giải
Đáp án đúng: "the control flow of a program is inverted". Inversion of Control là nguyên lý trong đó luồng điều khiển bị ĐẢO NGƯỢC so với lập trình thủ tục truyền thống: thay vì mã của bạn tự khởi tạo và gọi các thành phần phụ thuộc, framework hoặc container sẽ nắm quyền điều khiển và cung cấp chúng cho bạn - Dependency Injection chính là một cách hiện thực hoá IoC. Nhờ đó lớp chỉ khai báo cái nó cần chứ không quyết định cái nó dùng, giúp giảm ghép nối và dễ kiểm thử. Các phương án "A method for managing memory allocation.", "A technique for optimizing network traffic." và "A way to encrypt data." nói về quản lý bộ nhớ, tối ưu lưu lượng mạng và mã hoá, đều không liên quan.
Mở trang câu hỏi này →
18Consider this C# code:4 lựa chọncó code
Đề bài
public class FileLogger
{
   public void Log(string message)
     => Console.WriteLine(message);
}

public class OrderService
{
   private FileLogger logger = new FileLogger();
}

Which principle is violated here?

ASingle Responsibility Principle
BOpen/Closed Principle
CDependency Inversion Principle
DInterface Segregation Principle
Lời giải
Đáp án đúng: "Dependency Inversion Principle". OrderService tự khởi tạo một FileLogger cụ thể bằng new, nghĩa là mô-đun cấp cao phụ thuộc trực tiếp vào lớp hiện thực cấp thấp thay vì vào một trừu tượng như ILogger. Đó chính là vi phạm Nguyên lý Đảo ngược Phụ thuộc; cách sửa là khai báo interface ILogger, cho OrderService nhận nó qua constructor và để DI container cung cấp. Trách nhiệm của OrderService vẫn đơn nhất nên chưa vi phạm SRP ("Single Responsibility Principle"); không có chỗ nào phải sửa mã cũ để mở rộng nên chưa động tới OCP ("Open/Closed Principle"); và cũng không có interface phình to nào để nói tới ISP ("Interface Segregation Principle").
Mở trang câu hỏi này →
ATo create tightly coupled classes.
BTo depend on abstractions, not concretions.
CTo create large, monolithic classes.
DTo avoid using interfaces.
Lời giải
Đáp án đúng: "To depend on abstractions, not concretions". Nguyên lý Đảo ngược Phụ thuộc phát biểu rằng mô-đun cấp cao và mô-đun cấp thấp đều phải phụ thuộc vào TRỪU TƯỢNG, và trừu tượng không phụ thuộc vào chi tiết mà ngược lại. Mục đích là cắt đứt sự ràng buộc cứng giữa các lớp, giúp thay thế hiện thực, viết kiểm thử với đối tượng giả và mở rộng hệ thống dễ dàng. Phương án "To create tightly coupled classes" đi ngược mục tiêu vì tạo ra ghép nối chặt; "To create large, monolithic classes" nói về lớp lớn monolithic, thuộc vấn đề của SRP; "To avoid using interfaces" sai hoàn toàn vì DIP dựa chính vào interface.
Mở trang câu hỏi này →

Đề có câu hỏi của chủ đề này

4 đề chứa ít nhất một câu thuộc chủ đề — mở đề để làm cả bộ, không chỉ từng câu.