Can a class library have an App.config file?
Here is what my solution is looking like at the moment:
In the Tutomentor.Branding project, I'd like to save branding information in the App.开发者_运维问答config file, like names, colors, etc.
In the Tutomentor.Data project, the App.config was created when I added an entity .edmx model file.
Is this possible? Any recommendations?
When deploying, will the output COMBINE these App.config files into a single one?
No, class libraries can hold setting files, but their values will be defined in the application configuration (web.config, app.config...).
That's because of configuration settings overriding feature.
You'll need to declare the assemblies' configuration sections in the app.config or web.config of your application (WPF, SL, ASP.NET...) and define a value for a particular number of settings defined in the proper assembly settings.
EDIT: Add a setting file to your project and add a setting with application scope, and your assembly would have something like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Assembly1.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<Assembly1.Settings1>
<setting name="settingA" serializeAs="String">
<value>a value</value>
</setting>
</Assembly1.Settings1>
</applicationSettings>
</configuration>
Now you'd need to go to your application, and you need to copy-paste the section group, and section declarations, and the definition of the values for the settings. That's all.
While this is an older thread, It does warrent another look.
It seems you may want to look at the issue in a different way.
Class libraries by nature are supposed to be portable. So, any configuration needed should be passed to the class, instead of residing with the library. Things like connection strings are by nature transitory, so it makes sense to put them in the owning application.
When utilizing the methods contained in the library, you pass any needed information as part of the method's signature, or as a public property in the class. I suggest you create public properties for your configuration items, and pass them when you instantiate the class.
Now you have no issues with an app.config for the DLL, and the DLL is then truly portable.
Just create your own XML file, name it appConfig.xml or something similar, have your class library read the file using System.Xml instead of System.Configuration, and package the file along with your dll.
Any specific configuration from library app.config, you have to put in your exe configuration file manually.
You can add Settings File which will automatically generate app.config file.
And can Add the key value pairs in tabular form with the datatype specified. Then Access the values by calling Settings.Default.[KEY]
can reffer: https://www.technical-recipes.com/2018/creating-a-user-settings-class-library-for-your-c-project/
Well the class library can't have its own app.config, but if you define your settings the from the class library in the app.config for the exe file the class library should be able to find those to..
im a bit unsure but i don't think it will combine them automatically i guess you have to do i manually!
just use this common config to handle d.injection of services in class lib;
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDBContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
assembly => assembly.MigrationsAssembly(typeof(AppDBContext).Assembly.FullName));
});
services.AddScoped<IUsersRepository, UsersRepository>();
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseCors("MyPolicy");
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}
appsettingjson file:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "server=.;database=TestAPP;User ID=yener1;password=yener1;"
},
"AppSettings": {
"Secret": "REPLACE THIS WITH YOUR OWN SECRET, IT CAN BE ANY STRING"
},
"AllowedHosts": "*"
}
//commentout
public static class Hasher
{
public static string ToEncrypt<T>(this T value)
{
using (var sha256 = SHA256.Create())
{
// Send a sample text to hash.
var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(value.ToString()));
// Get the hashed string.
return BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
}
}
}
public class AppDBContext : DbContext
{
public AppDBContext(DbContextOptions options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public DbSet<Users> Users { get; set; }
//BLL
public class UsersRepository : IUsersRepository
{
private readonly AppDBContext _context;
public UsersRepository(AppDBContext context)
{
_context = context;
}
public async Task<IEnumerable<Users>> GetUsers()
{
return await _context.Users.ToListAsync();
}
[AllowAnonymous]
[HttpPost("authenticate")]
public IActionResult Authenticate([FromBody]UserDto userDto)
{
var user = _userService.Authenticate(userDto.Username, userDto.Password);
if (user == null)
return BadRequest("Username or password is incorrect");
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
// return basic user info (without password) and token to store client side
return Ok(new {
Id = user.Id,
Username = user.Username,
FirstName = user.FirstName,
LastName = user.LastName,
Token = tokenString
});
}
精彩评论