본문 바로가기
카테고리 없음

Singleton으로 NavigationManager를 사용해야 하는 경우 Host 주소 가져오기

by keisoft 2024. 11. 8.

Singleton으로 NavigationManager를 사용해야 하는 경우, 다음과 같은 방법들을 사용할 수 있습니다:

 

public class MyService
{
    private readonly NavigationManager _navigationManager;

    public MyService(NavigationManager navigationManager)
    {
        _navigationManager = navigationManager;
    }

    // 메서드에서 사용
    public string GetCurrentUrl()
    {
        return _navigationManager.Uri;
    }
}

 


1. IServiceProvider를 사용하는 방법:
```csharp
// 가장 안전한 방법
public class MySingletonService
{
    private readonly IServiceProvider _serviceProvider;

    public MySingletonService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public string GetCurrentUrl()
    {
        using var scope = _serviceProvider.CreateScope();
        var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
        return navigationManager.Uri;
    }
}

// Program.cs에서 등록
builder.Services.AddSingleton<MySingletonService>();
```

2. IHttpContextAccessor를 사용하는 방법:
```csharp
public class MySingletonService
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public MySingletonService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public string GetCurrentUrl()
    {
        var request = _httpContextAccessor.HttpContext?.Request;
        if (request != null)
        {
            return $"{request.Scheme}://{request.Host}{request.PathBase}{request.Path}";
        }
        return string.Empty;
    }
}

// Program.cs에서 등록
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<MySingletonService>();
```

3. 설정 값을 사용하는 방법:
```csharp
public class MySingletonService
{
    private readonly string _baseUrl;

    public MySingletonService(IConfiguration configuration)
    {
        _baseUrl = configuration["BaseUrl"] ?? "https://default-url.com";
    }

    public string GetBaseUrl() => _baseUrl;
}

// appsettings.json
{
  "BaseUrl": "https://your-domain.com"
}

// Program.cs에서 등록
builder.Services.AddSingleton<MySingletonService>();
```

4. Lazy 초기화를 사용하는 방법:
```csharp
public class MySingletonService
{
    private readonly Lazy<string> _baseUrl;
    private readonly IServiceProvider _serviceProvider;

    public MySingletonService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
        _baseUrl = new Lazy<string>(() =>
        {
            using var scope = _serviceProvider.CreateScope();
            var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
            return navigationManager.BaseUri;
        });
    }

    public string GetBaseUrl() => _baseUrl.Value;
}
```

5. 이벤트 기반 업데이트:
```csharp
public class MySingletonService
{
    private string _currentUrl;
    private readonly IServiceProvider _serviceProvider;

    public MySingletonService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void UpdateUrl()
    {
        using var scope = _serviceProvider.CreateScope();
        var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
        _currentUrl = navigationManager.Uri;
    }

    public string GetCurrentUrl()
    {
        if (string.IsNullOrEmpty(_currentUrl))
        {
            UpdateUrl();
        }
        return _currentUrl;
    }
}
```

6. URL 생성기 패턴:
```csharp
public class MySingletonService
{
    private readonly IServiceProvider _serviceProvider;

    public MySingletonService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public string GetUrl(string path)
    {
        using var scope = _serviceProvider.CreateScope();
        var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
        return navigationManager.ToAbsoluteUri(path).ToString();
    }
}
```

7. 캐싱을 사용하는 방법:
```csharp
public class MySingletonService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly IMemoryCache _cache;

    public MySingletonService(
        IServiceProvider serviceProvider,
        IMemoryCache cache)
    {
        _serviceProvider = serviceProvider;
        _cache = cache;
    }

    public string GetCurrentUrl()
    {
        return _cache.GetOrCreate("CurrentUrl", entry =>
        {
            entry.SlidingExpiration = TimeSpan.FromMinutes(5);
            using var scope = _serviceProvider.CreateScope();
            var navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
            return navigationManager.Uri;
        });
    }
}

// Program.cs에서 등록
builder.Services.AddMemoryCache();
builder.Services.AddSingleton<MySingletonService>();
```

사용 예시:
```csharp
// Controller나 다른 서비스에서 사용
public class SomeController : Controller
{
    private readonly MySingletonService _singletonService;

    public SomeController(MySingletonService singletonService)
    {
        _singletonService = singletonService;
    }

    public IActionResult Index()
    {
        var currentUrl = _singletonService.GetCurrentUrl();
        // ...
    }
}
```

주의사항:
1. IServiceProvider를 사용할 때는 반드시 using 구문으로 scope를 관리해야 합니다.
2. 캐싱을 사용할 때는 적절한 만료 시간을 설정해야 합니다.
3. URL이 자주 변경되는 경우 캐시 무효화 전략을 고려해야 합니다.
4. 성능이 중요한 경우 Lazy 초기화나 캐싱을 고려하세요.

이러한 방법들 중에서 애플리케이션의 요구사항과 성능 요구사항에 가장 적합한 방법을 선택하시면 됩니다.