安子 尽量多发现身边那些笑点很低,很容易满足,无论何时看起来都是喜洋洋的人,并且尽量多的跟他们在一起,你会感觉到被滋养,被激发,被启迪。它们像炭火一样煲养你的生命,给你力量,带来喜悦,他们是真正的人间天使。(更重要的,只要你贴他们足够近,他们还有能力把你转化成他们的同类)
碧螺姑娘 突然间真实感受到了“人生是旷野”的具体意义。虽然风刀霜剑严相催,但就是要热热闹闹地去活着。
奧匈帝國小説家弗朗茨·卡夫卡(Franz Kafka)寫過一則微型小説叫《法律門前》。小説講的是:有個鄉下人走到一處敞開的大門前,但是看門人不讓他進去。鄉下人問,那他以後可不可以進去呢?看門人跟他説,以後有可能,但是現在不行。看門人還暗示他說,如果他實在想進去,可以試一試,不過裏面還有更多看門人守著其他大門,這些看門人一個比一個難纏。後來這個鄉下人就在這個大門前等了一輩子,就等有機會允許他進去。等到自己快要死的時候,鄉下人問:爲什麽一直沒有其他人要求進這個大門?看門人跟他說:因爲這個大門就是專門給你一個人開的,等你死了,大門就會關起來。
人生若梦为欢几何 有句话说的很好,你把生活当游戏,把周围所有的人当npc,就不会内耗了。
CarrieZ 人类之所以进步,是因为下一代不听上一代的话。
…more
Wen working with QuickFix/n ibrary , efficient logging is crucial for troubleshooting. Here's how to implement a custom logging solution that routes QuickFix logs through NLog to your ELK stack.
Key Components
- NLogAdapter: A custom adapter that implements QuickFix's
ILog
interface:
public class NLogAdapter(ILogger logger) : ILog
{
private const string HeartbeatPattern = @"\x0135=0\x01";
private static readonly Regex HeartbeatRegex = new(HeartbeatPattern, RegexOptions.Compiled);
private static bool IsHeartBeat(string message) => HeartbeatRegex.IsMatch(message);
public void OnIncoming(string message)
{
if (!IsHeartBeat(message))
{
logger.Info("Incoming: {Message}", message);
}
}
// ... other implementations
}
- NLogQuickFixLogFactory: A factory class to create log instances:
public class NLogQuickFixLogFactory(ILog logger) : ILogFactory
{
public ILog Create(SessionID sessionId) => logger;
public ILog CreateNonSessionLog() => logger;
}
Implementation Steps
- Register Dependencies in your DI container:
builder.Services.AddSingleton<NLog.ILogger>(_ => LogManager.GetCurrentClassLogger());
builder.Services.AddSingleton<ILog, NLogAdapter>();
builder.Services.AddSingleton<ILogFactory, NLogQuickFixLogFactory>();
- Configure QuickFix to use the custom logger:
var initiator = new SocketInitiator(
clientApp,
storeFactory,
sessionSettings,
new NLogQuickFixLogFactory(quickfixLogger) // Use custom logger injeted by ILog here
);
Key Features
- Heartbeat Filtering: Reduces log noise by filtering out FIX heartbeat messages
- Structured Logging: Uses NLog's structured logging format for better parsing in ELK
- Separation of Concerns: Cleanly separates QuickFix logging from application logging
Benefits
- Centralized logging in ELK stack
- Better debugging apabilities
- Reduced log volume through heartbeat filtering
- Consistent logging format across your application
Here’s a consolidated list of common NUnit Assert
statements, categorized by their purpose. This should cover most of the common scenarios:
Basic Assertions
-
Equality:
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.EqualTo(expected));
-
Boolean Conditions:
Assert.That(condition, Is.True);
Assert.That(condition, Is.False);
-
Null Checks:
Assert.That(obj, Is.Null);
Assert.That(obj, Is.Not.Null);
String Assertions
-
Contains:
Assert.That(actualString, Does.Contain(substring));
-
Starts With / Ends With:
Assert.That(actualString, Does.StartWith(prefix));
Assert.That(actualString, Does.EndWith(suffix));
-
Empty or Not Empty:
Assert.That(actualString, Is.Empty);
Assert.That(actualString, Is.Not.Empty);
-
Matches Regex:
Assert.That(actualString, Does.Match(regexPattern));
Collection Assertions
-
Contains Item:
Assert.That(collection, Does.Contain(item));
-
Has Specific Count:
Assert.That(collection, Has.Count.EqualTo(expectedCount));
-
Empty or Not Empty:
Assert.That(collection, Is.Empty);
Assert.That(collection, Is.Not.Empty);
-
Unique Items:
Assert.That(collection, Is.Unique);
Numeric Assertions
-
Greater Than / Less Than:
Assert.That(actual, Is.GreaterThan(expected));
Assert.That(actual, Is.LessThan(expected));
-
Greater Than or Equal / Less Than or Equal:
Assert.That(actual, Is.GreaterThanOrEqualTo(expected));
Assert.That(actual, Is.LessThanOrEqualTo(expected));
-
In Range:
Assert.That(actual, Is.InRange(lower, upper));
Type Assertions
-
Instance of Type:
Assert.That(obj, Is.TypeOf<ExpectedType>());
Assert.That(obj, Is.InstanceOf<ExpectedType>());
-
Assignable From:
Assert.That(obj, Is.AssignableTo<ExpectedType>());
Exception Assertions
-
Throws Exception:
Assert.Throws<ExpectedExceptionType>(() => { methodCall(); });
-
Throws Specific Exception with Condition:
var ex = Assert.Throws<ExpectedExceptionType>(() => { methodCall(); });
Assert.That(ex.Message, Does.Contain("expected message"));
Miscellaneous
-
Same Instance:
Assert.That(actual, Is.SameAs(expected));
Assert.That(actual, Is.Not.SameAs(expected));
-
Applies a Condition:
Assert.That(collection, Has.Some.Matches<ExpectedType>(item => item.Condition));
-
Delayed Constraints (Asynchronous):
Assert.That(() => condition, Is.True.After(500).PollEvery(50));
-
Group related assertions together to improve readability and reporting:
Assert.Multiple(() =>
{
Assert.That(okResult, Is.Not.Null, "okResult should not be null");
Assert.That(okResult.Value, Is.TypeOf<string>(), "Value should be of type string");
});
The choice between = null!
and = string.Empty
depends on the context and the intent of the code. Here's a breakdown to help you decide:
= null!
When to Use:
-
You Intend to Initialize the Field Later:
-
Use = null!
when the property or field is expected to be set by a constructor, a method, or dependency injection after the object is created.
-
Example:
public string Name { get; set; } = null!;
-
Why: null!
tells the compiler to trust you that the value will be assigned before being accessed.
-
Avoid Premature Default Values:
- If a default value like
string.Empty
doesn't make sense for the context, null!
keeps the intent clearer.
-
For Models or Data Contracts:
-
In cases where fields are expected to match a schema or be deserialized from external sources, it might be better to indicate "unknown until set."
-
Example:
public string Username { get; set; } = null!; // Will be deserialized later
= string.Empty
When to Use:
-
Default Values Are Meaningful:
-
Use = string.Empty
when an empty string is a valid and reasonable default.
-
Example:
public string Name { get; set; } = string.Empty;
-
Why: This avoids null-checking or potential runtime errors when accessing the property.
-
Simpler to Work With:
- If the field/property is commonly accessed and null is not a meaningful value in your application, an empty string simplifies the logic (avoids extra null-checks).
-
UI or Display-Friendly Fields:
-
For fields used in UI contexts, empty strings often make more sense than null
:
public string Description { get; set; } = string.Empty;
Key Differences
Aspect |
= null! |
= string.Empty |
Purpose |
Indicates value will be set later. |
Provides an immediate, valid default. |
Compiler Warnings |
Suppresses nullability warnings (unsafe). |
Avoids nullability warnings entirely. |
Clarity |
Explicitly states "not initialized yet". |
Implies "initialized to empty value now". |
Best Fit |
Models, external contracts, DI patterns. |
Readily usable properties or fields. |
When to Avoid = null!
- When it's unclear who or what will initialize the property.
- When using
null
might lead to accidental runtime errors.
- When the property will be frequently accessed before initialization.
Recommendation
- Use
= string.Empty
when empty strings make sense as defaults and simplify code.
- Use
= null!
when initialization will occur later, and null isn't a valid or meaningful runtime value.
You know who is the real author of this article, don't you? :P