1+ using Microsoft . AspNetCore . Hosting ;
2+ using Microsoft . AspNetCore . Http ;
3+ using Microsoft . Extensions . Configuration ;
4+ using Microsoft . Extensions . DependencyInjection ;
5+ using System ;
6+ using System . Globalization ;
7+ using System . IO ;
8+ using System . Security . Principal ;
9+ using System . Threading ;
10+
11+ namespace Vaiona . Utils . Cfg
12+ {
13+ public class Constants
14+ {
15+ public static readonly string AnonymousUser = @"Anonymous" ;
16+ public static readonly string EveryoneRole = "Everyone" ;
17+ }
18+
19+ /// <summary>
20+ /// .NET Core version of AppConfiguration using dependency injection instead of static access.
21+ /// Replaces System.Web dependencies with ASP.NET Core equivalents.
22+ /// </summary>
23+ public class AppConfiguration
24+ {
25+ private readonly IConfiguration _configuration ;
26+ private readonly IWebHostEnvironment _environment ;
27+ private readonly IHttpContextAccessor _httpContextAccessor ;
28+ private readonly IServiceProvider _serviceProvider ;
29+
30+ public AppConfiguration (
31+ IConfiguration configuration ,
32+ IWebHostEnvironment environment ,
33+ IHttpContextAccessor httpContextAccessor ,
34+ IServiceProvider serviceProvider )
35+ {
36+ _configuration = configuration ;
37+ _environment = environment ;
38+ _httpContextAccessor = httpContextAccessor ;
39+ _serviceProvider = serviceProvider ;
40+ }
41+
42+ public bool IsWebContext => _httpContextAccessor . HttpContext != null ;
43+
44+ public bool IsPostBack ( HttpRequest request )
45+ {
46+ if ( request . Headers . Referer . Count == 0 ) return false ;
47+ if ( ! Uri . TryCreate ( request . Headers . Referer . ToString ( ) , UriKind . Absolute , out Uri refererUri ) ) return false ;
48+
49+ bool isPost = "POST" . Equals ( request . Method , StringComparison . CurrentCultureIgnoreCase ) ;
50+ bool isSameUrl = request . Path . Equals ( refererUri . AbsolutePath , StringComparison . CurrentCultureIgnoreCase ) ;
51+
52+ return isPost && isSameUrl ;
53+ }
54+
55+ public string DefaultApplicationConnection => _configuration . GetConnectionString ( "ApplicationServices" ) ;
56+
57+ public string DefaultCulture => _configuration [ "DefaultCulture" ] ?? "en-US" ;
58+
59+ public string DatabaseMappingFile => _configuration [ "DatabaseMappingFile" ] ?? string . Empty ;
60+
61+ public string DatabaseDialect => _configuration [ "DatabaseDialect" ] ?? "DB2Dialect" ;
62+
63+ public bool AutoCommitTransactions => _configuration . GetValue < bool > ( "AutoCommitTransactions" , false ) ;
64+
65+ public string IoCProviderTypeInfo => _configuration [ "IoCProviderTypeInfo" ] ?? string . Empty ;
66+
67+ public string AppRoot
68+ {
69+ get
70+ {
71+ // Try configuration first, then fall back to content root
72+ string path = _configuration [ "ApplicationRoot" ] ;
73+ return string . IsNullOrWhiteSpace ( path ) ? _environment . ContentRootPath : path ;
74+ }
75+ }
76+
77+ public string AreasPath
78+ {
79+ get
80+ {
81+ // Use WebRootPath instead of HostingEnvironment.MapPath
82+ string path = Path . Combine ( _environment . WebRootPath ?? _environment . ContentRootPath , "Areas" ) ;
83+ if ( Directory . Exists ( path ) )
84+ {
85+ return path ;
86+ }
87+ return Path . Combine ( AppRoot , "Areas" ) ;
88+ }
89+ }
90+
91+ /// <summary>
92+ /// DataPath shows the root folder containing business data.
93+ /// Uses IConfiguration instead of ConfigurationManager.AppSettings
94+ /// </summary>
95+ public string DataPath
96+ {
97+ get
98+ {
99+ string path = _configuration [ "DataPath" ] ;
100+ return string . IsNullOrWhiteSpace ( path ) ? Path . Combine ( AppRoot , "Data" ) : path ;
101+ }
102+ }
103+
104+ private string _workspaceRootPath = string . Empty ;
105+
106+ public string WorkspaceRootPath
107+ {
108+ get
109+ {
110+ if ( ! string . IsNullOrWhiteSpace ( _workspaceRootPath ) )
111+ return _workspaceRootPath ;
112+
113+ string path = _configuration [ "WorkspacePath" ] ?? string . Empty ;
114+ int level = 0 ;
115+
116+ if ( string . IsNullOrWhiteSpace ( path ) )
117+ level = 0 ;
118+ else if ( path . Contains ( @"..\" ) )
119+ {
120+ level = path . Split ( @"\" . ToCharArray ( ) ) . Length - 1 ;
121+ }
122+ else
123+ {
124+ _workspaceRootPath = path ;
125+ return _workspaceRootPath ;
126+ }
127+
128+ // Find directory without Web.config (use appsettings.json as indicator for web root)
129+ DirectoryInfo di = new DirectoryInfo ( AppRoot ) ;
130+ while ( di . GetFiles ( "appsettings.json" ) . Length >= 1 )
131+ di = di . Parent ;
132+
133+ for ( int i = 1 ; i < level ; i ++ )
134+ {
135+ di = di . Parent ;
136+ }
137+
138+ _workspaceRootPath = Path . Combine ( di . FullName , "Workspace" ) ;
139+ return _workspaceRootPath ;
140+ }
141+ }
142+
143+ public string WorkspaceComponentRoot => Path . Combine ( WorkspaceRootPath , "Components" ) ;
144+ public string WorkspaceModulesRoot => Path . Combine ( WorkspaceRootPath , "Modules" ) ;
145+ public string WorkspaceGeneralRoot => Path . Combine ( WorkspaceRootPath , "General" ) ;
146+ public string WorkspaceTenantsRoot => Path . Combine ( WorkspaceRootPath , "Tenants" ) ;
147+
148+ public string GetModuleWorkspacePath ( string moduleName ) => Path . Combine ( WorkspaceModulesRoot , moduleName ) ;
149+ public string GetComponentWorkspacePath ( string componentName ) => Path . Combine ( WorkspaceComponentRoot , componentName ) ;
150+
151+ public bool UseSchemaInDatabaseGeneration => _configuration . GetValue < bool > ( "UseSchemaInDatabaseGeneration" , false ) ;
152+ public bool CreateDatabase => _configuration . GetValue < bool > ( "CreateDatabase" , false ) ;
153+ public bool ShowQueries => _configuration . GetValue < bool > ( "ShowQueries" , false ) ;
154+
155+ private bool ? _cacheQueryResults = null ;
156+ public bool CacheQueryResults
157+ {
158+ get
159+ {
160+ if ( _cacheQueryResults . HasValue )
161+ return _cacheQueryResults . Value ;
162+
163+ _cacheQueryResults = _configuration . GetValue < bool > ( "CacheQueryResults" , false ) ;
164+ return _cacheQueryResults . Value ;
165+ }
166+ }
167+
168+ private string _themesPath ;
169+ public string ThemesPath
170+ {
171+ get
172+ {
173+ if ( ! string . IsNullOrEmpty ( _themesPath ) )
174+ return _themesPath ;
175+
176+ _themesPath = _configuration [ "ThemesPath" ] ?? "~/Themes" ;
177+ return _themesPath ;
178+ }
179+ }
180+
181+ private string _defaultThemeName ;
182+ public string DefaultThemeName
183+ {
184+ get
185+ {
186+ if ( ! string . IsNullOrEmpty ( _defaultThemeName ) )
187+ return _defaultThemeName ;
188+
189+ _defaultThemeName = _configuration [ "DefaultThemeName" ] ?? "Default" ;
190+ return _defaultThemeName ;
191+ }
192+ }
193+
194+ private string _activeLayoutName ;
195+ public string ActiveLayoutName
196+ {
197+ get
198+ {
199+ if ( ! string . IsNullOrEmpty ( _activeLayoutName ) )
200+ return _activeLayoutName ;
201+
202+ _activeLayoutName = _configuration [ "ActiveLayoutName" ] ?? "_Layout" ;
203+ return _activeLayoutName ;
204+ }
205+ }
206+
207+ public bool ThrowErrorWhenParialContentNotFound => _configuration . GetValue < bool > ( "ThrowErrorWhenParialContentNotFound" , false ) ;
208+
209+ // Replace HttpContext.Current with IHttpContextAccessor
210+ public HttpContext HttpContext => _httpContextAccessor . HttpContext ;
211+
212+ public Thread CurrentThread => Thread . CurrentThread ;
213+ public CultureInfo UICulture => Thread . CurrentThread . CurrentUICulture ;
214+ public CultureInfo Culture => Thread . CurrentThread . CurrentCulture ;
215+ public DateTime UTCDateTime => DateTime . UtcNow ;
216+ public DateTime DateTime => System . DateTime . Now ;
217+
218+ public byte [ ] GetUTCAsBytes ( ) => System . Text . Encoding . UTF8 . GetBytes ( UTCDateTime . ToBinary ( ) . ToString ( ) ) ;
219+
220+ public Uri CurrentRequestURL
221+ {
222+ get
223+ {
224+ try
225+ {
226+ var request = _httpContextAccessor . HttpContext ? . Request ;
227+ if ( request != null )
228+ {
229+ return new Uri ( $ "{ request . Scheme } ://{ request . Host } { request . Path } { request . QueryString } ") ;
230+ }
231+ return new Uri ( "http://NotFound.htm" ) ;
232+ }
233+ catch
234+ {
235+ return new Uri ( "http://NotFound.htm" ) ;
236+ }
237+ }
238+ }
239+
240+ public IPrincipal User
241+ {
242+ get
243+ {
244+ var httpContext = _httpContextAccessor . HttpContext ;
245+ if ( httpContext ? . User ? . Identity == null || ! httpContext . User . Identity . IsAuthenticated )
246+ {
247+ return CreateUser ( Constants . AnonymousUser , Constants . EveryoneRole ) ;
248+ }
249+ return httpContext . User ;
250+ }
251+ }
252+
253+ public bool TryGetCurrentUser ( ref string userName )
254+ {
255+ try
256+ {
257+ var httpContext = _httpContextAccessor . HttpContext ;
258+ userName = httpContext ? . User ? . Identity ? . Name ?? string . Empty ;
259+ return httpContext ? . User ? . Identity ? . IsAuthenticated ?? false ;
260+ }
261+ catch
262+ {
263+ return false ;
264+ }
265+ }
266+
267+ internal static IPrincipal CreateUser ( string userName , string roleName )
268+ {
269+ // Simplified user creation - in real implementation, integrate with ASP.NET Core Identity
270+ return new GenericPrincipal ( new GenericIdentity ( userName ) , new [ ] { roleName } ) ;
271+ }
272+
273+ // Logging properties with caching
274+ private bool ? _isLoggingEnable = null ;
275+ public bool IsLoggingEnable
276+ {
277+ get
278+ {
279+ if ( _isLoggingEnable . HasValue )
280+ return _isLoggingEnable . Value ;
281+
282+ _isLoggingEnable = _configuration . GetValue < bool > ( "IsLoggingEnable" , false ) ;
283+ return _isLoggingEnable . Value ;
284+ }
285+ }
286+
287+ private bool ? _isPerformanceLoggingEnable = null ;
288+ public bool IsPerformanceLoggingEnable
289+ {
290+ get
291+ {
292+ if ( _isPerformanceLoggingEnable . HasValue )
293+ return _isPerformanceLoggingEnable . Value ;
294+
295+ _isPerformanceLoggingEnable = _configuration . GetValue < bool > ( "IsPerformanceLoggingEnable" , false ) ;
296+ return _isPerformanceLoggingEnable . Value ;
297+ }
298+ }
299+
300+ private bool ? _isDiagnosticLoggingEnable = null ;
301+ public bool IsDiagnosticLoggingEnable
302+ {
303+ get
304+ {
305+ if ( _isDiagnosticLoggingEnable . HasValue )
306+ return _isDiagnosticLoggingEnable . Value ;
307+
308+ _isDiagnosticLoggingEnable = _configuration . GetValue < bool > ( "IsDiagnosticLoggingEnable" , false ) ;
309+ return _isDiagnosticLoggingEnable . Value ;
310+ }
311+ }
312+
313+ private bool ? _isCallLoggingEnable = null ;
314+ public bool IsCallLoggingEnable
315+ {
316+ get
317+ {
318+ if ( _isCallLoggingEnable . HasValue )
319+ return _isCallLoggingEnable . Value ;
320+
321+ _isCallLoggingEnable = _configuration . GetValue < bool > ( "IsCallLoggingEnable" , false ) ;
322+ return _isCallLoggingEnable . Value ;
323+ }
324+ }
325+
326+ private bool ? _isExceptionLoggingEnable = null ;
327+ public bool IsExceptionLoggingEnable
328+ {
329+ get
330+ {
331+ if ( _isExceptionLoggingEnable . HasValue )
332+ return _isExceptionLoggingEnable . Value ;
333+
334+ _isExceptionLoggingEnable = _configuration . GetValue < bool > ( "IsExceptionLoggingEnable" , false ) ;
335+ return _isExceptionLoggingEnable . Value ;
336+ }
337+ }
338+
339+ private bool ? _isDataLoggingEnable = null ;
340+ public bool IsDataLoggingEnable
341+ {
342+ get
343+ {
344+ if ( _isDataLoggingEnable . HasValue )
345+ return _isDataLoggingEnable . Value ;
346+
347+ _isDataLoggingEnable = _configuration . GetValue < bool > ( "IsDataLoggingEnable" , false ) ;
348+ return _isDataLoggingEnable . Value ;
349+ }
350+ }
351+
352+ private string _tenantId = "" ;
353+ public string TenantId
354+ {
355+ get
356+ {
357+ if ( ! string . IsNullOrWhiteSpace ( _tenantId ) )
358+ return _tenantId ;
359+
360+ _tenantId = _configuration [ "TenantId" ] ?? string . Empty ;
361+ return _tenantId ;
362+ }
363+ }
364+
365+ private int ? _conversationIsolationLevel = null ;
366+ public int ConversationIsolationLevel
367+ {
368+ get
369+ {
370+ if ( _conversationIsolationLevel . HasValue )
371+ return _conversationIsolationLevel . Value ;
372+
373+ _conversationIsolationLevel = _configuration . GetValue < int > ( "ConversationIsolationLevel" , 2 ) ;
374+ return _conversationIsolationLevel . Value ;
375+ }
376+ }
377+ }
378+
379+ /// <summary>
380+ /// Extension methods for registering AppConfiguration in .NET Core DI container
381+ /// </summary>
382+ public static class AppConfigurationExtensions
383+ {
384+ public static IServiceCollection AddAppConfiguration ( this IServiceCollection services )
385+ {
386+ services . AddHttpContextAccessor ( ) ;
387+ services . AddSingleton < AppConfiguration > ( ) ;
388+ return services ;
389+ }
390+ }
391+ }
0 commit comments