diskpart
list disk
select disk <the disk number>
clean
Check when Active Directory password expires
net user /domain <username> | findstr /i expires
Share a new Angular module with multiple standalone components
// material-components.module.ts
const modules = [
CommonModule,
MatAutocompleteModule,
MatButtonModule,
MatCardModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatListModule,
MatSortModule,
MatTableModule
];
@NgModule({
imports: modules,
exports: modules
})
export class MaterialComponentsModule { }
// home.component.ts
@Component({
selector: 'app-home',
standalone: true,
imports: [MaterialComponentsModule],
templateUrl: './home.component.html',
styleUrl: './home.component.scss'
})
export class HomeComponent {
Repeat an observable in Angular (RXJS)
interval(1000).subscribe(() => {
this._getLatest().subscribe(latest => {
//...
});
});
Set static IP in linux
determine the name of your network interface
ip a
make a backup of the netplan configuration
sudo cp /etc/netplan/01-network-manager-all.yaml /etc/netplan/01-network-manager-all.yaml.backup
edit the config file
sudo vim.tiny /etc/netplan/01-network-manager-all.yaml
make the following changes, replacing “interface_name” with the intended interface
network:
version: 2
renderer: networkd
ethernets:
interface_name:
addresses:
- 192.168.1.101/24
nameservers:
addresses: [8.8.8.8]
routes:
- to: default
via: 192.168.1.1
try the new configuration
sudo netplan try
If all is good, press ENTER
Insert into a MsSQL table that only has auto-generated columns
INSERT INTO table_name DEFAULT VALUES
New angular app is missing environment.ts and environment.prod.ts
The ng new
command no longer automatically includes environments. You must run the following:
ng g environments
Disable the Windows “Shake” feature
Shaking the mouse while dragging another window’s title bar minimizes all other Windows. The UI to disable this “feature” is no longer obvious and I was able to disable it by making the following registry change. Note: This worked even on a gpo machine since it only modified CURRENT_USER.
registry location
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced
Add the following DWORD key with value 1
DisallowShaking
Angular pipe to replace characters in a string
Generate a new pipe using the Angular CLI
ng g pipe pipes/replace
Code inside the new pipe (pipes/replace.pipe.ts)
...
transform(input: string, from: string, to: string): string {
const regEx = new RegExp(from, 'g');
return input.replace(regEx, to);
}
Usage
// page.component.html
// replaces underscores with spaces
...
<span>{{ myString | replace:'_':' '}}</span>
Display enums as strings in Swagger/Swashbuckle (.net6)
// Program.cs
builder.Services.AddControllers().AddJsonOptions(opt =>
{
opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
Mock a non-singleton Angular service in a component unit test
describe('MyComponent', () => {
let mockService: jasmine.SpyObj<MyService>;
beforeEach(async () => {
mockService = jasmine.createSpyObj<MyService>(['download']);
await TestBed.configureTestingModule({
...
}).overrideComponent(MyComponent, {
set: {
providers: [
{ provide: MyService, useValue: mockService }]
}
}).compileComponents();
beforeEach(() => {
...
});
it('should create', () => {
...
});
});
Add theme switching to Angular Material
// styles.scss
$dark-theme: mat.define-dark-theme(
vars.$primaryPalette,
vars.$accentPalette,
vars.$warnPalette);
$light-theme: mat.define-light-theme(
vars.$primaryPalette,
vars.$accentPalette,
vars.$warnPalette);
.light-theme {
@include mat.all-component-themes($light-theme);
}
.dark-theme {
@include mat.all-component-themes($dark-theme);
}
// app.component.ts
constructor(
private _settingsService: SettingsService,
@Inject(DOCUMENT) private _document: Document) { }
ngOnInit(): void {
this._settingsService.theme$.subscribe(theme => {
if (theme === Themes.DARK) {
this._setDarkTheme();
} else {
this._setLightTheme();
}
});
}
private _setDarkTheme(): void {
this._document.documentElement.classList.add(Themes.DARK);
this._document.documentElement.classList.remove(Themes.LIGHT);
}
private _setLightTheme(): void {
this._document.documentElement.classList.add(Themes.LIGHT);
this._document.documentElement.classList.remove(Themes.DARK);
}
This is just a summary, so some of the more trivial parts are omitted.
ref: https://octoperf.com/blog/2021/01/08/angular-material-multiple-themes
Do not ignore case with git cli
git config --global core.ignorecase false
Show environmental PATH variable in Windows cmd / terminal
echo %PATH:;=&echo.%
Assert DoesNotThrow in XUnit
// Act
var ex = await Record.ExceptionAsync(() => _thing.DoSomethingAsync());
// Assert
Assert.Null(ex);
Configuration Extension Examples
AutoMapper Configuration
using AutoMapper;
using Christopher.Snay.Sample.Configuration.AutoMapperProfiles;
using Christopher.Snay.Sample.Configuration.AutoMapperProfiles.Dtos;
using Microsoft.Extensions.DependencyInjection;
namespace Christopher.Snay.Sample.Configuration
{
public static class AutoMapperConfiguration
{
public static void AddAutoMapperConfiguration(this IServiceCollection services)
{
services.AddSingleton(new MapperConfiguration(config =>
{
config.AddProfile<SampleMapperProfile1>();
config.AddProfile<SampleMapperProfile2>();
}).CreateMapper());
}
}
}
CORS Configuration
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Christopher.Snay.Sample.Configuration
{
public static class CorsConfiguration
{
public static IApplicationBuilder UseCorsConfiguration(this IApplicationBuilder app)
{
return app.UseCors("CorsPolicy");
}
public static IServiceCollection AddCorsConfiguration(this IServiceCollection services)
{
var origins = new List<string>
{
"http://localhost:4200",
"http://sample-server",
};
return services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder =>
{
builder
.WithOrigins(origins.ToArray())
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
}
}
}
HttpClientFactory Configuration
using System.Net.Http.Headers;
using System.Net.Mime;
using Christopher.Snay.Sample.Services.RetailerServices;
using Microsoft.Extensions.DependencyInjection;
namespace Christopher.Snay.Sample.Configuration
{
public static class HttpConfiguration
{
public static void AddHttpClientConfiguration(this IServiceCollection services)
{
services.AddHttpClient(nameof(ISampleService1), x => x.BaseAddress
= new Uri("https://www.api.sample.com/search"));
services.AddHttpClient(nameof(ISampleService2), x => x.BaseAddress
= new Uri("https://www.api.sample2.com/search"));
services.AddHttpClient(nameof(ISampleService3), x =>
{
x.BaseAddress = new Uri("https://www.api.sample3.com/search");
x.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue("Mozilla", "5.0")));
x.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
x.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
x.DefaultRequestHeaders.Host = "www.sample.com";
x.DefaultRequestHeaders.Connection.Add("keep-alive");
x.DefaultRequestHeaders.Add("cookie", "Bearer ABC123");
}
}
}
}
Scrape rendered HTML with .NET6 C#
using HtmlAgilityPack;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.PhantomJS;
namespace Christopher.Snay.Sample.Services.Scrapers
{
internal class ChromeScraper : IChromeScraper
{
public HtmlDocument ScrapeHtml(Uri url)
{
return ScrapeHtml(url.ToString());
}
public HtmlDocument ScrapeHtml(string url)
{
HtmlDocument doc = new();
using (PhantomJSDriverService driverService = PhantomJSDriverService.CreateDefaultService())
{
driverService.HideCommandPromptWindow = true;
driverService.LoadImages = false;
driverService.IgnoreSslErrors = true;
driverService.Start();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(url);
Thread.Sleep(3000);
doc.LoadHtml(driver.PageSource);
}
return doc;
}
}
public interface IChromeScraper
{
HtmlDocument ScrapeHtml(string url);
HtmlDocument ScrapeHtml(Uri url);
}
}
Requirements – The following executables must be in /bin
- phantonjs.exe
- chrome.exe
- chromedriver.exe
- + the chrome portable binaries directory, currently named \107.0.5304.88
<!-- To copy directly to bin without being placed in a sub-folder -->
<ItemGroup>
<ContentWithTargetPath Include="Assets\phantomjs.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>phantomjs.exe</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Assets\chrome.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>chrome.exe</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Assets\chromedriver.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>chromedriver.exe</TargetPath>
</ContentWithTargetPath>
<None Include="Assets\phantomjs.exe" />
<None Include="Assets\chrome.exe" />
<None Include="Assets\chromedriver.exe" />
</ItemGroup>
I’ve used Chrome portable to avoid having to install Chrome. If Chrome is installed, the chrome.exe steps can probably be skipped.
A Better Generic Repository for Entity Framework
using System.Linq.Expressions;
using Christopher.Snay.Sample.DataAccess.Database;
using Microsoft.EntityFrameworkCore;
namespace Christopher.Snay.Sample.DataAccess.Repositories
{
internal sealed class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly SampleDbContext _db;
public Repository(SampleDbContext db)
{
_db = db;
}
public TEntity? Get(int id)
{
return _db.Set<TEntity>().Find(id);
}
public IEnumerable<TEntity> All()
{
return _db.Set<TEntity>().AsEnumerable();
}
public IEnumerable<TEntity> All<TChild>(
Expression<Func<TEntity, TChild>> includePredicate)
{
return _db.Set<TEntity>().Include(includePredicate).AsEnumerable();
}
public IEnumerable<TEntity> All<TChild, TGrandChild>(
Expression<Func<TEntity, TChild>> includePredicate,
Expression<Func<TChild, TGrandChild>> thenIncludePredicate)
{
return _db.Set<TEntity>().Include(includePredicate)
.ThenInclude(thenIncludePredicate).AsEnumerable();
}
public TEntity? Select(Expression<Func<TEntity, bool>> predicate)
{
return _db.Set<TEntity>().FirstOrDefault(predicate);
}
public TEntity? Select<TChild>(Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate)
{
return _db.Set<TEntity>().Include(includePredicate).FirstOrDefault(predicate);
}
public TEntity? Select<TChild, TGrandChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate,
Expression<Func<TChild, TGrandChild>> thenIncludePredicate)
{
return _db.Set<TEntity>().Include(includePredicate)
.ThenInclude(thenIncludePredicate).FirstOrDefault(predicate);
}
public IEnumerable<TEntity> SelecyMany(Expression<Func<TEntity, bool>> predicate)
{
return _db.Set<TEntity>().Where(predicate).AsEnumerable();
}
public IEnumerable<TEntity> SelecyMany<TChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate)
{
return _db.Set<TEntity>().Include(includePredicate).Where(predicate).AsEnumerable();
}
public IEnumerable<TEntity> SelecyMany<TChild, TGrandChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate,
Expression<Func<TChild, TGrandChild>> thenIncludePredicate)
{
return _db.Set<TEntity>().Include(includePredicate)
.ThenInclude(thenIncludePredicate).Where(predicate).AsEnumerable();
}
public void Insert(TEntity entity)
{
_db.Set<TEntity>().Add(entity);
}
public void Insert(List<TEntity> entities)
{
_db.Set<TEntity>().AddRange(entities);
}
public void Update(TEntity entity)
{
_db.Set<TEntity>().Update(entity);
}
public void Update(List<TEntity> entities)
{
_db.Set<TEntity>().UpdateRange(entities);
}
public void Delete(TEntity entity)
{
_db.Set<TEntity>().Remove(entity);
}
public void Delete(List<TEntity> entities)
{
_db.Set<TEntity>().RemoveRange(entities);
}
public int SaveChanges()
{
return _db.SaveChanges();
}
}
public interface IRepository<TEntity> where TEntity : class
{
TEntity? Get(int id);
IEnumerable<TEntity> All();
IEnumerable<TEntity> All<TChild>(Expression<Func<TEntity, TChild>> includePredicate);
IEnumerable<TEntity> All<TChild, TGrandChild>(
Expression<Func<TEntity, TChild>> includePredicate,
Expression<Func<TChild, TGrandChild>> thenIncludePredicate);
TEntity? Select(Expression<Func<TEntity, bool>> predicate);
TEntity? Select<TChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate);
TEntity? Select<TChild, TGrandChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate,
Expression<Func<TChild, TGrandChild>> thenIncludePredicate);
IEnumerable<TEntity> SelecyMany(Expression<Func<TEntity, bool>> predicate);
IEnumerable<TEntity> SelecyMany<TChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate);
IEnumerable<TEntity> SelecyMany<TChild, TGrandChild>(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, TChild>> includePredicate,
Expression<Func<TChild, TGrandChild>> thenIncludePredicate);
void Insert(TEntity entity);
void Insert(List<TEntity> entities);
void Update(TEntity entity);
void Update(List<TEntity> entities);
void Delete(TEntity entity);
void Delete(List<TEntity> entities);
int SaveChanges();
}
}
Serialize object/model to XML
string xml;
using (var writer = new StringWriter())
{
var serializer = new XmlSerializer(typeof(MyModel));
serializer.Serialize(writer, myModel);
xml = writer.ToString();
}
Set default value of a GUID field in Entity Framework Sqlite vs MsSql
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuidler.Entity<MyEntity>(entity =>
if (_settings.UseSql)
{
entity.Property(e => e.Id)
.HasColumnName("id")
.HasDefaultValueSql("(newid())");
}
else if (_settings.UseSqlite)
{
entity.Property(e => e.Id)
.HasColumnName("id")
.HasDefaultValue(Guid.NewGuid());
}
....
}