ಸ್ಕೇಲೆಬಲ್, ನಿರ್ವಹಿಸಬಲ್ಲ, ಮತ್ತು ಪರೀಕ್ಷಿಸಬಲ್ಲ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು FastAPI ನಲ್ಲಿ ಸುಧಾರಿತ ಡಿಪೆಂಡೆನ್ಸಿ ಇಂಜೆಕ್ಷನ್ ಮಾದರಿಗಳನ್ನು ಅನ್ವೇಷಿಸಿ. ದೃಢವಾದ DI ಕಂಟೇನರ್ ರಚಿಸುವುದನ್ನು ಕಲಿಯಿರಿ.
FastAPI ಡಿಪೆಂಡೆನ್ಸಿ ಇಂಜೆಕ್ಷನ್: ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಆರ್ಕಿಟೆಕ್ಚರ್
FastAPI, ತನ್ನ ಸಹಜ ವಿನ್ಯಾಸ ಮತ್ತು ಶಕ್ತಿಯುತ ವೈಶಿಷ್ಟ್ಯಗಳೊಂದಿಗೆ, ಪೈಥಾನ್ನಲ್ಲಿ ಆಧುನಿಕ ವೆಬ್ API ಗಳನ್ನು ನಿರ್ಮಿಸಲು ನೆಚ್ಚಿನ ಆಯ್ಕೆಯಾಗಿದೆ. ಡಿಪೆಂಡೆನ್ಸಿ ಇಂಜೆಕ್ಷನ್ (DI) ನೊಂದಿಗೆ ಅದರ ಸುಲಲಿತ ಏಕೀಕರಣವು ಅದರ ಪ್ರಮುಖ ಶಕ್ತಿಗಳಲ್ಲಿ ಒಂದಾಗಿದೆ. ಇದು ಡೆವಲಪರ್ಗಳಿಗೆ ಲೂಸ್ಲಿ ಕಪಲ್ಡ್, ಪರೀಕ್ಷಿಸಬಹುದಾದ ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದಾದ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ರಚಿಸಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. FastAPI ಯ ಅಂತರ್ನಿರ್ಮಿತ DI ವ್ಯವಸ್ಥೆಯು ಸರಳ ಬಳಕೆಯ ಸಂದರ್ಭಗಳಿಗೆ ಅತ್ಯುತ್ತಮವಾಗಿದ್ದರೂ, ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾದ ಯೋಜನೆಗಳು ಹೆಚ್ಚು ರಚನಾತ್ಮಕ ಮತ್ತು ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಆರ್ಕಿಟೆಕ್ಚರ್ನಿಂದ ಪ್ರಯೋಜನ ಪಡೆಯುತ್ತವೆ. ಈ ಲೇಖನವು ಅಂತಹ ಆರ್ಕಿಟೆಕ್ಚರ್ ಅನ್ನು ನಿರ್ಮಿಸಲು ವಿವಿಧ ತಂತ್ರಗಳನ್ನು ಅನ್ವೇಷಿಸುತ್ತದೆ, ದೃಢವಾದ ಮತ್ತು ಸ್ಕೇಲೆಬಲ್ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸಲು ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳು ಮತ್ತು ಒಳನೋಟಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ.
ಡಿಪೆಂಡೆನ್ಸಿ ಇಂಜೆಕ್ಷನ್ (DI) ಮತ್ತು ಇನ್ವರ್ಶನ್ ಆಫ್ ಕಂಟ್ರೋಲ್ (IoC) ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು
ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಆರ್ಕಿಟೆಕ್ಚರ್ಗಳನ್ನು ಪರಿಶೀಲಿಸುವ ಮೊದಲು, ಮೂಲಭೂತ ಪರಿಕಲ್ಪನೆಗಳನ್ನು ಸ್ಪಷ್ಟಪಡಿಸೋಣ:
- Dependency Injection (DI): ಒಂದು ಡಿಸೈನ್ ಪ್ಯಾಟರ್ನ್, ಇದರಲ್ಲಿ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಆಂತರಿಕವಾಗಿ ರಚಿಸುವ ಬದಲು ಬಾಹ್ಯ ಮೂಲಗಳಿಂದ ಒಂದು ಕಾಂಪೊನೆಂಟ್ಗೆ ಒದಗಿಸಲಾಗುತ್ತದೆ. ಇದು ಲೂಸ್ ಕಪ್ಲಿಂಗ್ ಅನ್ನು ಉತ್ತೇಜಿಸುತ್ತದೆ, ಇದರಿಂದಾಗಿ ಕಾಂಪೊನೆಂಟ್ಗಳನ್ನು ಪರೀಕ್ಷಿಸಲು ಮತ್ತು ಮರುಬಳಕೆ ಮಾಡಲು ಸುಲಭವಾಗುತ್ತದೆ.
- Inversion of Control (IoC): ಒಂದು ವಿಶಾಲವಾದ ತತ್ವ, ಇದರಲ್ಲಿ ಆಬ್ಜೆಕ್ಟ್ ರಚನೆ ಮತ್ತು ನಿರ್ವಹಣೆಯ ನಿಯಂತ್ರಣವನ್ನು ತಿರುಗಿಸಲಾಗುತ್ತದೆ – ಅಂದರೆ, ಒಂದು ಫ್ರೇಮ್ವರ್ಕ್ ಅಥವಾ ಕಂಟೇನರ್ಗೆ ವಹಿಸಲಾಗುತ್ತದೆ. DIಯು IoC ಯ ಒಂದು ನಿರ್ದಿಷ್ಟ ಪ್ರಕಾರವಾಗಿದೆ.
FastAPI ತನ್ನ ಡಿಪೆಂಡೆನ್ಸಿ ಸಿಸ್ಟಮ್ ಮೂಲಕ DI ಅನ್ನು ಸಹಜವಾಗಿ ಬೆಂಬಲಿಸುತ್ತದೆ. ನೀವು ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಕರೆಯಬಹುದಾದ ಆಬ್ಜೆಕ್ಟ್ಗಳಾಗಿ (ಫಂಕ್ಷನ್ಗಳು, ಕ್ಲಾಸ್ಗಳು, ಇತ್ಯಾದಿ) ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೀರಿ ಮತ್ತು FastAPI ಅವುಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಪರಿಹರಿಸಿ ನಿಮ್ಮ ಎಂಡ್ಪಾಯಿಂಟ್ ಫಂಕ್ಷನ್ಗಳು ಅಥವಾ ಇತರ ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗೆ ಇಂಜೆಕ್ಟ್ ಮಾಡುತ್ತದೆ.
ಉದಾಹರಣೆ (ಮೂಲಭೂತ FastAPI DI):
from fastapi import FastAPI, Depends
app = FastAPI()
# Dependency
def get_db():
db = {"items": []} # Simulate a database connection
try:
yield db
finally:
# Close the database connection (if needed)
pass
# Endpoint with dependency injection
@app.get("/items/")
async def read_items(db: dict = Depends(get_db)):
return db["items"]
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, get_db ಎಂಬುದು ಡೇಟಾಬೇಸ್ ಸಂಪರ್ಕವನ್ನು ಒದಗಿಸುವ ಒಂದು ಡಿಪೆಂಡೆನ್ಸಿ. FastAPI ಸ್ವಯಂಚಾಲಿತವಾಗಿ get_db ಅನ್ನು ಕರೆಯುತ್ತದೆ ಮತ್ತು ಅದರ ಫಲಿತಾಂಶವನ್ನು (db ಡಿಕ್ಷನರಿ) read_items ಎಂಡ್ಪಾಯಿಂಟ್ ಫಂಕ್ಷನ್ಗೆ ಇಂಜೆಕ್ಟ್ ಮಾಡುತ್ತದೆ.
ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಏಕೆ ಬೇಕು?
FastAPI ಯ ಅಂತರ್ನಿರ್ಮಿತ DI ಸರಳ ಯೋಜನೆಗಳಿಗೆ ಚೆನ್ನಾಗಿ ಕೆಲಸ ಮಾಡುತ್ತದೆ, ಆದರೆ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಸಂಕೀರ್ಣತೆಯಲ್ಲಿ ಬೆಳೆದಂತೆ, ಹೆಚ್ಚು ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಹಲವಾರು ಪ್ರಯೋಜನಗಳನ್ನು ನೀಡುತ್ತದೆ:
- Centralized Dependency Management: ಒಂದು ಮೀಸಲಾದ ಕಂಟೇನರ್ ಎಲ್ಲಾ ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗೆ ಏಕೈಕ ಸತ್ಯದ ಮೂಲವನ್ನು ಒದಗಿಸುತ್ತದೆ, ಇದರಿಂದಾಗಿ ಅಪ್ಲಿಕೇಶನ್ನ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಮತ್ತು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಸುಲಭವಾಗುತ್ತದೆ.
- Configuration and Lifecycle Management: ಕಂಟೇನರ್ ಡಿಪೆಂಡೆನ್ಸಿಗಳ ಕಾನ್ಫಿಗರೇಶನ್ ಮತ್ತು ಲೈಫ್ಸೈಕಲ್ ಅನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ, ಉದಾಹರಣೆಗೆ ಸಿಂಗಲ್ಟನ್ಗಳನ್ನು ರಚಿಸುವುದು, ಸಂಪರ್ಕಗಳನ್ನು ನಿರ್ವಹಿಸುವುದು ಮತ್ತು ಸಂಪನ್ಮೂಲಗಳನ್ನು ವಿಲೇವಾರಿ ಮಾಡುವುದು.
- Testability: ಸುಧಾರಿತ ಕಂಟೇನರ್, ಮಾಕ್ ಆಬ್ಜೆಕ್ಟ್ಗಳು ಅಥವಾ ಟೆಸ್ಟ್ ಡಬಲ್ಗಳೊಂದಿಗೆ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಸುಲಭವಾಗಿ ಓವರ್ರೈಡ್ ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ಮೂಲಕ ಟೆಸ್ಟಿಂಗ್ ಅನ್ನು ಸರಳಗೊಳಿಸುತ್ತದೆ.
- Decoupling: ಕಾಂಪೊನೆಂಟ್ಗಳ ನಡುವೆ ಹೆಚ್ಚಿನ ಡಿಕಪ್ಲಿಂಗ್ ಅನ್ನು ಉತ್ತೇಜಿಸುತ್ತದೆ, ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ಕೋಡ್ ನಿರ್ವಹಣೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ.
- Extensibility: ವಿಸ್ತರಿಸಬಲ್ಲ ಕಂಟೇನರ್ ಅಗತ್ಯವಿದ್ದಾಗ ಕಸ್ಟಮ್ ವೈಶಿಷ್ಟ್ಯಗಳು ಮತ್ತು ಇಂಟಿಗ್ರೇಷನ್ಗಳನ್ನು ಸೇರಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.
ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ನಿರ್ಮಿಸುವ ತಂತ್ರಗಳು
FastAPI ಯಲ್ಲಿ ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ನಿರ್ಮಿಸಲು ಹಲವಾರು ವಿಧಾನಗಳಿವೆ. ಕೆಲವು ಸಾಮಾನ್ಯ ತಂತ್ರಗಳು ಇಲ್ಲಿವೆ:
1. ಮೀಸಲಾದ DI ಲೈಬ್ರರಿ ಬಳಸುವುದು (ಉದಾಹರಣೆಗೆ, `injector`, `dependency_injector`)
ಪೈಥಾನ್ಗೆ injector ಮತ್ತು dependency_injector ನಂತಹ ಹಲವಾರು ಶಕ್ತಿಯುತ DI ಲೈಬ್ರರಿಗಳು ಲಭ್ಯವಿದೆ. ಈ ಲೈಬ್ರರಿಗಳು ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಸಮಗ್ರ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಒದಗಿಸುತ್ತವೆ, ಅವುಗಳೆಂದರೆ:
- Binding: ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಹೇಗೆ ಪರಿಹರಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಇಂಜೆಕ್ಟ್ ಮಾಡಲಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುವುದು.
- Scopes: ಡಿಪೆಂಡೆನ್ಸಿಗಳ ಲೈಫ್ಸೈಕಲ್ ಅನ್ನು ನಿಯಂತ್ರಿಸುವುದು (ಉದಾಹರಣೆಗೆ, ಸಿಂಗಲ್ಟನ್, ಟ್ರಾನ್ಸಿಯೆಂಟ್).
- Configuration: ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗಾಗಿ ಕಾನ್ಫಿಗರೇಶನ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನಿರ್ವಹಿಸುವುದು.
- AOP (Aspect-Oriented Programming): ಕ್ರಾಸ್-ಕಟಿಂಗ್ ಕಾಳಜಿಗಳಿಗಾಗಿ ಮೆಥಡ್ ಕಾಲ್ಗಳನ್ನು ತಡೆಹಿಡಿಯುವುದು.
`dependency_injector` ನೊಂದಿಗೆ ಉದಾಹರಣೆ
dependency_injector DI ಕಂಟೇನರ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ಜನಪ್ರಿಯ ಆಯ್ಕೆಯಾಗಿದೆ. ಅದರ ಬಳಕೆಯನ್ನು ಒಂದು ಉದಾಹರಣೆಯೊಂದಿಗೆ ವಿವರಿಸೋಣ:
from dependency_injector import containers, providers
from fastapi import FastAPI, Depends
# Define dependencies
class Database:
def __init__(self, connection_string: str):
self.connection_string = connection_string
# Initialize database connection
print(f"Connecting to database: {self.connection_string}")
def get_items(self):
# Simulate fetching items from the database
return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]
class UserRepository:
def __init__(self, database: Database):
self.database = database
def get_all_users(self):
# Simulating database request to get all users
return [{"id": "user1", "name": "Alice"},{"id": "user2", "name": "Bob"}]
class Settings:
def __init__(self, database_url):
self.database_url = database_url
# Define container
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
settings = providers.Singleton(Settings, database_url = config.database_url)
database = providers.Singleton(Database, connection_string=config.database_url)
user_repository = providers.Factory(UserRepository, database=database)
# Create FastAPI app
app = FastAPI()
# Configure container (from an environment variable)
container = Container()
container.config.database_url.from_env("DATABASE_URL", default="sqlite:///:memory:")
container.wire([__name__]) # enables injection of dependencies into FastAPI endpoints
# Dependency for FastAPI
def get_user_repository(user_repository: UserRepository = Depends(container.user_repository.provided)) -> UserRepository:
return user_repository
# Endpoint using injected dependency
@app.get("/users/")
async def read_users(user_repository: UserRepository = Depends(get_user_repository)):
return user_repository.get_all_users()
@app.on_event("startup")
async def startup_event():
# Container initialization
container.init_resources()
ವಿವರಣೆ:
- ನಾವು ನಮ್ಮ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು (
Database,UserRepository,Settings) ಸಾಮಾನ್ಯ ಪೈಥಾನ್ ಕ್ಲಾಸ್ಗಳಾಗಿ ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೇವೆ. - ನಾವು
containers.DeclarativeContainerನಿಂದ ಇನ್ಹೆರಿಟ್ ಆಗುವContainerಕ್ಲಾಸ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ. ಈ ಕ್ಲಾಸ್ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಮತ್ತು ಅವುಗಳ ಪ್ರೊವೈಡರ್ಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ (ಉದಾಹರಣೆಗೆ, ಸಿಂಗಲ್ಟನ್ಗಳಿಗಾಗಿproviders.Singleton, ಪ್ರತಿ ಬಾರಿ ಹೊಸ ಇನ್ಸ್ಟೆನ್ಸ್ ರಚಿಸಲುproviders.Factory). container.wire([__name__])ಲೈನ್ FastAPI ಎಂಡ್ಪಾಯಿಂಟ್ಗಳಿಗೆ ಡಿಪೆಂಡೆನ್ಸಿ ಇಂಜೆಕ್ಷನ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ.get_user_repositoryಫಂಕ್ಷನ್ ಒಂದು FastAPI ಡಿಪೆಂಡೆನ್ಸಿಯಾಗಿದ್ದು, ಇದು ಕಂಟೇನರ್ನಿಂದ UserRepository ಇನ್ಸ್ಟೆನ್ಸ್ ಅನ್ನು ಪಡೆಯಲುcontainer.user_repository.providedಅನ್ನು ಬಳಸುತ್ತದೆ.- ಎಂಡ್ಪಾಯಿಂಟ್ ಫಂಕ್ಷನ್
read_usersUserRepositoryಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ಇಂಜೆಕ್ಟ್ ಮಾಡುತ್ತದೆ. configನಿಮಗೆ ಡಿಪೆಂಡೆನ್ಸಿ ಕಾನ್ಫಿಗರೇಶನ್ಗಳನ್ನು ಬಾಹ್ಯೀಕರಿಸಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದನ್ನು ಎನ್ವಿರಾನ್ಮೆಂಟ್ ವೇರಿಯೇಬಲ್ಗಳು, ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್ಗಳು ಇತ್ಯಾದಿಗಳಿಂದ ಪಡೆಯಬಹುದು.startup_eventಅನ್ನು ಕಂಟೇನರ್ನಲ್ಲಿ ನಿರ್ವಹಿಸಲಾದ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಇನಿಶಿಯಲೈಸ್ ಮಾಡಲು ಬಳಸಲಾಗುತ್ತದೆ.
2. ಕಸ್ಟಮ್ DI ಕಂಟೇನರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು
DI ಪ್ರಕ್ರಿಯೆಯ ಮೇಲೆ ಹೆಚ್ಚು ನಿಯಂತ್ರಣಕ್ಕಾಗಿ, ನೀವು ಕಸ್ಟಮ್ DI ಕಂಟೇನರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು. ಈ ವಿಧಾನಕ್ಕೆ ಹೆಚ್ಚು ಪ್ರಯತ್ನ ಬೇಕಾಗುತ್ತದೆ ಆದರೆ ನಿಮ್ಮ ನಿರ್ದಿಷ್ಟ ಅಗತ್ಯಗಳಿಗೆ ಅನುಗುಣವಾಗಿ ಕಂಟೇನರ್ ಅನ್ನು ರೂಪಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.
ಮೂಲಭೂತ ಕಸ್ಟಮ್ DI ಕಂಟೇನರ್ ಉದಾಹರಣೆ:
from typing import Callable, Dict, Type, Any
from fastapi import FastAPI, Depends
class Container:
def __init__(self):
self.dependencies: Dict[Type[Any], Callable[..., Any]] = {}
self.instances: Dict[Type[Any], Any] = {}
def register(self, dependency_type: Type[Any], provider: Callable[..., Any]):
self.dependencies[dependency_type] = provider
def resolve(self, dependency_type: Type[Any]) -> Any:
if dependency_type in self.instances:
return self.instances[dependency_type]
if dependency_type not in self.dependencies:
raise Exception(f"Dependency {dependency_type} not registered.")
provider = self.dependencies[dependency_type]
instance = provider()
return instance
def singleton(self, dependency_type: Type[Any], provider: Callable[..., Any]):
self.register(dependency_type, provider)
self.instances[dependency_type] = provider()
# Example Dependencies
class PaymentGateway:
def process_payment(self, amount: float) -> bool:
print(f"Processing payment of ${amount}")
return True # Simulate successful payment
class NotificationService:
def send_notification(self, message: str):
print(f"Sending notification: {message}")
# Example Usage
container = Container()
container.singleton(PaymentGateway, PaymentGateway)
container.singleton(NotificationService, NotificationService)
app = FastAPI()
# FastAPI Dependency
def get_payment_gateway(payment_gateway: PaymentGateway = Depends(lambda: container.resolve(PaymentGateway))):
return payment_gateway
def get_notification_service(notification_service: NotificationService = Depends(lambda: container.resolve(NotificationService))):
return notification_service
@app.post("/purchase/")
async def purchase_item(payment_gateway: PaymentGateway = Depends(get_payment_gateway), notification_service: NotificationService = Depends(get_notification_service)):
if payment_gateway.process_payment(100.0):
notification_service.send_notification("Purchase successful!")
return {"message": "Purchase successful"}
else:
return {"message": "Purchase failed"}
ವಿವರಣೆ:
Containerಕ್ಲಾಸ್ ಡಿಪೆಂಡೆನ್ಸಿಗಳು ಮತ್ತು ಅವುಗಳ ಪ್ರೊವೈಡರ್ಗಳ ಡಿಕ್ಷನರಿಯನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ.registerಮೆಥಡ್ ಒಂದು ಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ಅದರ ಪ್ರೊವೈಡರ್ನೊಂದಿಗೆ ನೋಂದಾಯಿಸುತ್ತದೆ.resolveಮೆಥಡ್ ಅದರ ಪ್ರೊವೈಡರ್ ಅನ್ನು ಕರೆಯುವ ಮೂಲಕ ಒಂದು ಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ಪರಿಹರಿಸುತ್ತದೆ.singletonಮೆಥಡ್ ಒಂದು ಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ನೋಂದಾಯಿಸುತ್ತದೆ ಮತ್ತು ಅದರ ಏಕೈಕ ಇನ್ಸ್ಟೆನ್ಸ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ.- ಕಂಟೇನರ್ನಿಂದ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಪರಿಹರಿಸಲು FastAPI ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಲ್ಯಾಂಬ್ಡಾ ಫಂಕ್ಷನ್ ಬಳಸಿ ರಚಿಸಲಾಗಿದೆ.
3. ಫ್ಯಾಕ್ಟರಿ ಫಂಕ್ಷನ್ನೊಂದಿಗೆ FastAPI ಯ `Depends` ಬಳಸುವುದು
ಪೂರ್ಣ ಪ್ರಮಾಣದ DI ಕಂಟೇನರ್ ಬದಲಿಗೆ, ನೀವು FastAPI ಯ Depends ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಫಂಕ್ಷನ್ಗಳೊಂದಿಗೆ ಬಳಸಿ ಕೆಲವು ಮಟ್ಟದ ಡಿಪೆಂಡೆನ್ಸಿ ನಿರ್ವಹಣೆಯನ್ನು ಸಾಧಿಸಬಹುದು. ಈ ವಿಧಾನವು ಕಸ್ಟಮ್ ಕಂಟೇನರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದಕ್ಕಿಂತ ಸರಳವಾಗಿದೆ ಆದರೆ ಎಂಡ್ಪಾಯಿಂಟ್ ಫಂಕ್ಷನ್ಗಳ ಒಳಗೆ ನೇರವಾಗಿ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಇನ್ಸ್ಟಾಂಟಿಯೇಟ್ ಮಾಡುವುದಕ್ಕಿಂತ ಕೆಲವು ಪ್ರಯೋಜನಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ.
from fastapi import FastAPI, Depends
from typing import Callable
# Define Dependencies
class EmailService:
def __init__(self, smtp_server: str):
self.smtp_server = smtp_server
def send_email(self, recipient: str, subject: str, body: str):
print(f"Sending email to {recipient} via {self.smtp_server}: {subject} - {body}")
# Factory function for EmailService
def create_email_service(smtp_server: str) -> EmailService:
return EmailService(smtp_server=smtp_server)
# FastAPI
app = FastAPI()
# FastAPI Dependency, leveraging factory function and Depends
def get_email_service(email_service: EmailService = Depends(lambda: create_email_service(smtp_server="smtp.example.com"))):
return email_service
@app.post("/send-email/")
async def send_email(recipient: str, subject: str, body: str, email_service: EmailService = Depends(get_email_service)):
email_service.send_email(recipient=recipient, subject=subject, body=body)
return {"message": "Email sent!"}
ವಿವರಣೆ:
- ನಾವು
EmailServiceಡಿಪೆಂಡೆನ್ಸಿಯ ಇನ್ಸ್ಟೆನ್ಸ್ಗಳನ್ನು ರಚಿಸುವ ಫ್ಯಾಕ್ಟರಿ ಫಂಕ್ಷನ್ (create_email_service) ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೇವೆ. get_email_serviceಡಿಪೆಂಡೆನ್ಸಿ ಫ್ಯಾಕ್ಟರಿ ಫಂಕ್ಷನ್ ಅನ್ನು ಕರೆಯಲು ಮತ್ತುEmailServiceನ ಇನ್ಸ್ಟೆನ್ಸ್ ಅನ್ನು ಒದಗಿಸಲುDependsಮತ್ತು ಲ್ಯಾಂಬ್ಡಾವನ್ನು ಬಳಸುತ್ತದೆ.- ಎಂಡ್ಪಾಯಿಂಟ್ ಫಂಕ್ಷನ್
send_emailEmailServiceಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ಇಂಜೆಕ್ಟ್ ಮಾಡುತ್ತದೆ.
ಸುಧಾರಿತ ಪರಿಗಣನೆಗಳು
1. ಸ್ಕೋಪ್ಗಳು ಮತ್ತು ಲೈಫ್ಸೈಕಲ್ಗಳು
DI ಕಂಟೇನರ್ಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಡಿಪೆಂಡೆನ್ಸಿಗಳ ಲೈಫ್ಸೈಕಲ್ ಅನ್ನು ನಿರ್ವಹಿಸಲು ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಒದಗಿಸುತ್ತವೆ. ಸಾಮಾನ್ಯ ಸ್ಕೋಪ್ಗಳು ಇವುಗಳನ್ನು ಒಳಗೊಂಡಿವೆ:
- Singleton: ಡಿಪೆಂಡೆನ್ಸಿಯ ಒಂದೇ ಇನ್ಸ್ಟೆನ್ಸ್ ಅನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್ನ ಜೀವಿತಾವಧಿಯಾದ್ಯಂತ ಮರುಬಳಕೆ ಮಾಡಲಾಗುತ್ತದೆ. ಸ್ಟೇಟ್ಲೆಸ್ ಅಥವಾ ಜಾಗತಿಕ ಸ್ಕೋಪ್ ಹೊಂದಿರುವ ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗೆ ಇದು ಸೂಕ್ತವಾಗಿದೆ.
- Transient: ಪ್ರತಿ ಬಾರಿ ವಿನಂತಿಸಿದಾಗ ಡಿಪೆಂಡೆನ್ಸಿಯ ಹೊಸ ಇನ್ಸ್ಟೆನ್ಸ್ ಅನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ. ಸ್ಟೇಟ್ಫುಲ್ ಅಥವಾ ಪರಸ್ಪರ ಪ್ರತ್ಯೇಕವಾಗಿರಬೇಕಾದ ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗೆ ಇದು ಸೂಕ್ತವಾಗಿದೆ.
- Request: ಪ್ರತಿ ಒಳಬರುವ ವಿನಂತಿಗೆ ಡಿಪೆಂಡೆನ್ಸಿಯ ಒಂದೇ ಇನ್ಸ್ಟೆನ್ಸ್ ಅನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ. ಒಂದೇ ವಿನಂತಿಯ ಸಂದರ್ಭದಲ್ಲಿ ಸ್ಟೇಟ್ ಅನ್ನು ನಿರ್ವಹಿಸಬೇಕಾದ ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗೆ ಇದು ಸೂಕ್ತವಾಗಿದೆ.
dependency_injector ಲೈಬ್ರರಿಯು ಸ್ಕೋಪ್ಗಳಿಗೆ ಅಂತರ್ನಿರ್ಮಿತ ಬೆಂಬಲವನ್ನು ಒದಗಿಸುತ್ತದೆ. ಕಸ್ಟಮ್ ಕಂಟೇನರ್ಗಳಿಗಾಗಿ, ನೀವು ಸ್ಕೋಪ್ ನಿರ್ವಹಣಾ ಲಾಜಿಕ್ ಅನ್ನು ನೀವೇ ಕಾರ್ಯಗತಗೊಳಿಸಬೇಕಾಗುತ್ತದೆ.
2. ಕಾನ್ಫಿಗರೇಶನ್
ಡಿಪೆಂಡೆನ್ಸಿಗಳಿಗೆ ಸಾಮಾನ್ಯವಾಗಿ ಕಾನ್ಫಿಗರೇಶನ್ ಸೆಟ್ಟಿಂಗ್ಗಳು ಬೇಕಾಗುತ್ತವೆ, ಉದಾಹರಣೆಗೆ ಡೇಟಾಬೇಸ್ ಕನೆಕ್ಷನ್ ಸ್ಟ್ರಿಂಗ್ಗಳು, API ಕೀಗಳು ಮತ್ತು ಫೀಚರ್ ಫ್ಲ್ಯಾಗ್ಗಳು. DI ಕಂಟೇನರ್ಗಳು ಕಾನ್ಫಿಗರೇಶನ್ ಮೌಲ್ಯಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಮತ್ತು ಇಂಜೆಕ್ಟ್ ಮಾಡಲು ಕೇಂದ್ರೀಕೃತ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುವ ಮೂಲಕ ಈ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತವೆ.
dependency_injector ಉದಾಹರಣೆಯಲ್ಲಿ, config ಪ್ರೊವೈಡರ್ ಎನ್ವಿರಾನ್ಮೆಂಟ್ ವೇರಿಯೇಬಲ್ಗಳಿಂದ ಕಾನ್ಫಿಗರೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಕಸ್ಟಮ್ ಕಂಟೇನರ್ಗಳಿಗಾಗಿ, ನೀವು ಫೈಲ್ಗಳು ಅಥವಾ ಎನ್ವಿರಾನ್ಮೆಂಟ್ ವೇರಿಯೇಬಲ್ಗಳಿಂದ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಲೋಡ್ ಮಾಡಬಹುದು ಮತ್ತು ಅವುಗಳನ್ನು ಕಂಟೇನರ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಬಹುದು.
3. ಟೆಸ್ಟಿಂಗ್
DI ಯ ಪ್ರಮುಖ ಪ್ರಯೋಜನಗಳಲ್ಲಿ ಒಂದು ಸುಧಾರಿತ ಟೆಸ್ಟಬಿಲಿಟಿ. DI ಕಂಟೇನರ್ನೊಂದಿಗೆ, ನೀವು ಟೆಸ್ಟಿಂಗ್ ಸಮಯದಲ್ಲಿ ನಿಜವಾದ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಮಾಕ್ ಆಬ್ಜೆಕ್ಟ್ಗಳು ಅಥವಾ ಟೆಸ್ಟ್ ಡಬಲ್ಗಳೊಂದಿಗೆ ಸುಲಭವಾಗಿ ಬದಲಾಯಿಸಬಹುದು.
ಉದಾಹರಣೆ (`dependency_injector` ನೊಂದಿಗೆ ಟೆಸ್ಟಿಂಗ್):
import pytest
from unittest.mock import MagicMock
from dependency_injector import containers, providers
from fastapi import FastAPI, Depends
from fastapi.testclient import TestClient
# Define dependencies (same as before)
class Database:
def __init__(self, connection_string: str):
self.connection_string = connection_string
def get_items(self):
return [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]
class UserRepository:
def __init__(self, database: Database):
self.database = database
def get_all_users(self):
return [{"id": "user1", "name": "Alice"},{"id": "user2", "name": "Bob"}]
class Settings:
def __init__(self, database_url):
self.database_url = database_url
# Define container (same as before)
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
settings = providers.Singleton(Settings, database_url = config.database_url)
database = providers.Singleton(Database, connection_string=config.database_url)
user_repository = providers.Factory(UserRepository, database=database)
# Create FastAPI app (same as before)
app = FastAPI()
# Configure container (from an environment variable)
container = Container()
container.config.database_url.from_env("DATABASE_URL", default="sqlite:///:memory:")
container.wire([__name__]) # enables injection of dependencies into FastAPI endpoints
# Dependency for FastAPI
def get_user_repository(user_repository: UserRepository = Depends(container.user_repository.provided)) -> UserRepository:
return user_repository
# Endpoint using injected dependency (same as before)
@app.get("/users/")
async def read_users(user_repository: UserRepository = Depends(get_user_repository)):
return user_repository.get_all_users()
@app.on_event("startup")
async def startup_event():
# Container initialization
container.init_resources()
# Test
@pytest.fixture
def test_client():
# Override the database dependency with a mock
database_mock = MagicMock(spec=Database)
database_mock.get_items.return_value = [{"id": 3, "name": "Test Item"}]
user_repository_mock = MagicMock(spec = UserRepository)
user_repository_mock.get_all_users.return_value = [{"id": "test_user", "name": "Test User"}]
# Override container with mock dependencies
container.user_repository.override(providers.Factory(lambda: user_repository_mock))
with TestClient(app) as client:
yield client
container.user_repository.reset()
def test_read_users(test_client: TestClient):
response = test_client.get("/users/")
assert response.status_code == 200
assert response.json() == [{"id": "test_user", "name": "Test User"}]
ವಿವರಣೆ:
- ನಾವು
MagicMockಬಳಸಿDatabaseಡಿಪೆಂಡೆನ್ಸಿಗಾಗಿ ಮಾಕ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ರಚಿಸುತ್ತೇವೆ. - ನಾವು
container.database.override()ಬಳಸಿ ಕಂಟೇನರ್ನಲ್ಲಿನdatabaseಪ್ರೊವೈಡರ್ ಅನ್ನು ಮಾಕ್ ಆಬ್ಜೆಕ್ಟ್ನೊಂದಿಗೆ ಓವರ್ರೈಡ್ ಮಾಡುತ್ತೇವೆ. - ಟೆಸ್ಟ್ ಫಂಕ್ಷನ್
test_read_itemsಈಗ ಮಾಕ್ ಡೇಟಾಬೇಸ್ ಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ಬಳಸುತ್ತದೆ. - ಟೆಸ್ಟ್ ಮುಗಿದ ನಂತರ, ಇದು ಕಂಟೇನರ್ನ ಓವರ್ರೈಡ್ ಮಾಡಲಾದ ಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ರಿಸೆಟ್ ಮಾಡುತ್ತದೆ.
4. ಅಸಿಂಕ್ರೋನಸ್ ಡಿಪೆಂಡೆನ್ಸಿಗಳು
FastAPI ಅನ್ನು ಅಸಿಂಕ್ರೋನಸ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್ (async/await) ಮೇಲೆ ನಿರ್ಮಿಸಲಾಗಿದೆ. ಅಸಿಂಕ್ರೋನಸ್ ಡಿಪೆಂಡೆನ್ಸಿಗಳೊಂದಿಗೆ (ಉದಾಹರಣೆಗೆ, ಅಸಿಂಕ್ರೋನಸ್ ಡೇಟಾಬೇಸ್ ಸಂಪರ್ಕಗಳು) ಕೆಲಸ ಮಾಡುವಾಗ, ನಿಮ್ಮ DI ಕಂಟೇನರ್ ಮತ್ತು ಡಿಪೆಂಡೆನ್ಸಿ ಪ್ರೊವೈಡರ್ಗಳು ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಬೆಂಬಲಿಸುತ್ತವೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.
ಉದಾಹರಣೆ (`dependency_injector` ನೊಂದಿಗೆ ಅಸಿಂಕ್ರೋನಸ್ ಡಿಪೆಂಡೆನ್ಸಿ):
import asyncio
from dependency_injector import containers, providers
from fastapi import FastAPI, Depends
# Define asynchronous dependency
class AsyncDatabase:
def __init__(self, connection_string: str):
self.connection_string = connection_string
async def connect(self):
print(f"Connecting to database: {self.connection_string}")
await asyncio.sleep(0.1) # Simulate connection time
async def fetch_data(self):
await asyncio.sleep(0.1) # Simulate database query
return [{"id": 1, "name": "Async Item 1"}]
# Define container
class Container(containers.DeclarativeContainer):
config = providers.Configuration()
database = providers.Singleton(AsyncDatabase, connection_string=config.database_url)
# Create FastAPI app
app = FastAPI()
# Configure container
container = Container()
container.config.database_url.from_env("DATABASE_URL", default="sqlite:///:memory:")
container.wire([__name__])
# Dependency for FastAPI
async def get_async_database(database: AsyncDatabase = Depends(container.database.provided)) -> AsyncDatabase:
await database.connect()
return database
# Endpoint using injected dependency
@app.get("/async-items/")
async def read_async_items(database: AsyncDatabase = Depends(get_async_database)):
data = await database.fetch_data()
return data
@app.on_event("startup")
async def startup_event():
# Container initialization
container.init_resources()
ವಿವರಣೆ:
AsyncDatabaseಕ್ಲಾಸ್asyncಮತ್ತುawaitಬಳಸಿ ಅಸಿಂಕ್ರೋನಸ್ ಮೆಥಡ್ಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ.get_async_databaseಡಿಪೆಂಡೆನ್ಸಿಯನ್ನು ಸಹ ಅಸಿಂಕ್ರೋನಸ್ ಫಂಕ್ಷನ್ ಆಗಿ ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ.- ಎಂಡ್ಪಾಯಿಂಟ್ ಫಂಕ್ಷನ್
read_async_itemsಅನ್ನುasyncಎಂದು ಗುರುತಿಸಲಾಗಿದೆ ಮತ್ತುdatabase.fetch_data()ಫಲಿತಾಂಶಕ್ಕಾಗಿ ಕಾಯುತ್ತದೆ.
ಸರಿಯಾದ ವಿಧಾನವನ್ನು ಆರಿಸುವುದು
ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಅನ್ನು ನಿರ್ಮಿಸಲು ಉತ್ತಮ ವಿಧಾನವು ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನ ಸಂಕೀರ್ಣತೆ ಮತ್ತು ನಿಮ್ಮ ನಿರ್ದಿಷ್ಟ ಅವಶ್ಯಕತೆಗಳನ್ನು ಅವಲಂಬಿಸಿರುತ್ತದೆ:
- ಸಣ್ಣ ಮತ್ತು ಮಧ್ಯಮ ಗಾತ್ರದ ಯೋಜನೆಗಳಿಗೆ: FastAPI ಯ ಅಂತರ್ನಿರ್ಮಿತ DI ಅಥವಾ
Dependsನೊಂದಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಫಂಕ್ಷನ್ ವಿಧಾನವು ಸಾಕಾಗಬಹುದು. - ದೊಡ್ಡ, ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾದ ಯೋಜನೆಗಳಿಗೆ:
dependency_injectorನಂತಹ ಮೀಸಲಾದ DI ಲೈಬ್ರರಿಯು ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಸಮಗ್ರ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. - DI ಪ್ರಕ್ರಿಯೆಯ ಮೇಲೆ ಸೂಕ್ಷ್ಮ ನಿಯಂತ್ರಣದ ಅಗತ್ಯವಿರುವ ಯೋಜನೆಗಳಿಗೆ: ಕಸ್ಟಮ್ DI ಕಂಟೇನರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು ಅತ್ಯುತ್ತಮ ಆಯ್ಕೆಯಾಗಿರಬಹುದು.
ತೀರ್ಮಾನ
ಡಿಪೆಂಡೆನ್ಸಿ ಇಂಜೆಕ್ಷನ್ ಸ್ಕೇಲೆಬಲ್, ನಿರ್ವಹಿಸಬಲ್ಲ ಮತ್ತು ಪರೀಕ್ಷಿಸಬಲ್ಲ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ಒಂದು ಶಕ್ತಿಯುತ ತಂತ್ರವಾಗಿದೆ. FastAPI ಯ ಅಂತರ್ನಿರ್ಮಿತ DI ವ್ಯವಸ್ಥೆಯು ಸರಳ ಬಳಕೆಯ ಸಂದರ್ಭಗಳಿಗೆ ಅತ್ಯುತ್ತಮವಾಗಿದ್ದರೂ, ಸುಧಾರಿತ DI ಕಂಟೇನರ್ ಆರ್ಕಿಟೆಕ್ಚರ್ ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾದ ಯೋಜನೆಗಳಿಗೆ ಗಮನಾರ್ಹ ಪ್ರಯೋಜನಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. ಸರಿಯಾದ ವಿಧಾನವನ್ನು ಆರಿಸುವ ಮೂಲಕ ಮತ್ತು DI ಲೈಬ್ರರಿಗಳ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬಳಸಿಕೊಳ್ಳುವ ಮೂಲಕ ಅಥವಾ ಕಸ್ಟಮ್ ಕಂಟೇನರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮೂಲಕ, ನೀವು ದೃಢವಾದ ಮತ್ತು ಹೊಂದಿಕೊಳ್ಳುವ ಡಿಪೆಂಡೆನ್ಸಿ ನಿರ್ವಹಣಾ ವ್ಯವಸ್ಥೆಯನ್ನು ರಚಿಸಬಹುದು, ಇದು ನಿಮ್ಮ FastAPI ಅಪ್ಲಿಕೇಶನ್ಗಳ ಒಟ್ಟಾರೆ ಗುಣಮಟ್ಟ ಮತ್ತು ನಿರ್ವಹಣೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ.
ಜಾಗತಿಕ ಪರಿಗಣನೆಗಳು
ಜಾಗತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ DI ಕಂಟೇನರ್ಗಳನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸುವಾಗ, ಈ ಕೆಳಗಿನವುಗಳನ್ನು ಪರಿಗಣಿಸುವುದು ಮುಖ್ಯ:
- Localization: ಸ್ಥಳೀಕರಣಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು (ಉದಾಹರಣೆಗೆ, ಭಾಷಾ ಸೆಟ್ಟಿಂಗ್ಗಳು, ದಿನಾಂಕ ಸ್ವರೂಪಗಳು) ವಿವಿಧ ಪ್ರದೇಶಗಳಲ್ಲಿ ಸ್ಥಿರತೆಯನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು DI ಕಂಟೇನರ್ನಿಂದ ನಿರ್ವಹಿಸಬೇಕು.
- Time Zones: ಟೈಮ್ ಝೋನ್ ಮಾಹಿತಿಯನ್ನು ಹಾರ್ಡ್ಕೋಡ್ ಮಾಡುವುದನ್ನು ತಪ್ಪಿಸಲು ಟೈಮ್ ಝೋನ್ ಪರಿವರ್ತನೆಗಳನ್ನು ನಿರ್ವಹಿಸುವ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಇಂಜೆಕ್ಟ್ ಮಾಡಬೇಕು.
- Currency: ವಿವಿಧ ಕರೆನ್ಸಿಗಳನ್ನು ಬೆಂಬಲಿಸಲು ಕರೆನ್ಸಿ ಪರಿವರ್ತನೆ ಮತ್ತು ಫಾರ್ಮ್ಯಾಟಿಂಗ್ಗಾಗಿ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಕಂಟೇನರ್ನಿಂದ ನಿರ್ವಹಿಸಬೇಕು.
- Regional Settings: ಇತರ ಪ್ರಾದೇಶಿಕ ಸೆಟ್ಟಿಂಗ್ಗಳಾದ ಸಂಖ್ಯೆ ಸ್ವರೂಪಗಳು ಮತ್ತು ವಿಳಾಸ ಸ್ವರೂಪಗಳನ್ನು ಸಹ DI ಕಂಟೇನರ್ನಿಂದ ನಿರ್ವಹಿಸಬೇಕು.
- Multi-tenancy: ಮಲ್ಟಿ-ಟೆನೆಂಟ್ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ, DI ಕಂಟೇನರ್ ವಿವಿಧ ಟೆನೆಂಟ್ಗಳಿಗೆ ವಿಭಿನ್ನ ಡಿಪೆಂಡೆನ್ಸಿಗಳನ್ನು ಒದಗಿಸಲು ಸಾಧ್ಯವಾಗಬೇಕು. ಇದನ್ನು ಸ್ಕೋಪ್ಗಳು ಅಥವಾ ಕಸ್ಟಮ್ ಡಿಪೆಂಡೆನ್ಸಿ ರೆಸಲ್ಯೂಶನ್ ಲಾಜಿಕ್ ಬಳಸಿ ಸಾಧಿಸಬಹುದು.
- Compliance and Security: ನಿಮ್ಮ ಡಿಪೆಂಡೆನ್ಸಿ ನಿರ್ವಹಣಾ ತಂತ್ರವು ಸಂಬಂಧಿತ ಡೇಟಾ ಗೌಪ್ಯತೆ ನಿಯಮಗಳಿಗೆ (ಉದಾಹರಣೆಗೆ, GDPR, CCPA) ಮತ್ತು ವಿವಿಧ ಪ್ರದೇಶಗಳಲ್ಲಿನ ಭದ್ರತಾ ಉತ್ತಮ ಅಭ್ಯಾಸಗಳಿಗೆ ಅನುಗುಣವಾಗಿದೆಯೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ. ಸೂಕ್ಷ್ಮ ರುಜುವಾತುಗಳು ಮತ್ತು ಕಾನ್ಫಿಗರೇಶನ್ಗಳನ್ನು ಕಂಟೇನರ್ನಲ್ಲಿ ಸುರಕ್ಷಿತವಾಗಿ ನಿರ್ವಹಿಸಿ.
ಈ ಜಾಗತಿಕ ಅಂಶಗಳನ್ನು ಪರಿಗಣಿಸುವ ಮೂಲಕ, ಜಾಗತಿಕ ಪರಿಸರದಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ಸೂಕ್ತವಾದ DI ಕಂಟೇನರ್ಗಳನ್ನು ನೀವು ರಚಿಸಬಹುದು.