์๋ฌธ: https://devblogs.microsoft.com/dotnet/dotnet-11-preview-3/
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋ฐ์ดํธ
System.Text.Json: ์ด๋ฆ ์ง์ ๋ฐ ๋ฌด์ ๊ธฐ๋ณธ๊ฐ ์ ์ด ์ต์ ๊ฐํ
Preview 3์์๋ System.Text.Json์ ๊ธฐ๋ณธ์ ๊ณต ๋ช
๋ช
๋ฐ ๋ฌด์ ์ต์
์ด ํ์ฅ๋์์ต๋๋ค. ๊ธฐ์กด์ camel, snake, kebab ํ๋ฆฌ์
์ ๋ํด JsonNamingPolicy.PascalCase๊ฐ ์ถ๊ฐ๋์์ผ๋ฉฐ, [JsonNamingPolicy]๋ฅผ ํตํด ๊ฐ๋ณ ๋ฉค๋ฒ ๋จ์๋ก ๋ช
๋ช
์ ์ฑ
์ ์ฌ์ ์ํ ์ ์์ต๋๋ค. ๋ํ ํ์ ์์ค์ [JsonIgnore(Condition = ...)]๋ฅผ ํตํด ๋ชจ๋ธ์ ๊ธฐ๋ณธ ๋ฌด์ ๋์์ ํ ๊ณณ์์ ์ค์ ํ ์ ์์ต๋๋ค (dotnet/runtime #124644, dotnet/runtime #124645, dotnet/runtime #124646).
using System.Text.Json;
using System.Text.Json.Serialization;
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public sealed class EventData
{
[JsonNamingPolicy(JsonKnownNamingPolicy.CamelCase)]
public string EventName { get; set; } = "";
public string? Notes { get; set; }
}
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.PascalCase
};
Zstandard: System.IO.Compression์ผ๋ก ์ด๋, ZIP ์ฝ๊ธฐ ์ CRC32 ๊ฒ์ฆ
์ด์ ์ .NET 11์์ ์๊ฐ๋์๋ Zstandard API๊ฐ ์ด์ System.IO.Compression์ ํฌํจ๋์ด DeflateStream, GZipStream, BrotliStream๊ณผ ๋๋ํ์์นํ๊ฒ ๋์์ต๋๋ค (dotnet/runtime #124634). ๋ํ Preview 3์์๋ ZIP ํญ๋ชฉ์ ์ฝ์ ๋ CRC32 ๊ฒ์ฆ์ด ์ถ๊ฐ๋์ด, ์์๋ ํ์ด๋ก๋๋ฅผ ๋ฌต์ธํ๋ ๋์ InvalidDataException์ผ๋ก ๋๋น ๋ฅด๊ฒ ์คํจํฉ๋๋ค(dotnet/runtime #124766). ์ด์ ํ๋ฆฌ๋ทฐ ํจํค์ง๋ฅผ ์ฌ์ฉ ์ค์ด์๋ค๋ฉด ๋ณ๋์ System.IO.Compression.Zstandard ํจํค์ง ์ฐธ์กฐ๋ฅผ ์ ๊ฑฐํ์ธ์.
-<PackageReference Include="System.IO.Compression.Zstandard" />
SafeFileHandle ๋ฐ RandomAccess: ํ์ดํ ์ง์ ํ์ฅ
Preview 3์๋ ๋ช ๊ฐ์ง ์ ์์ค I/O ์
๋ฐ์ดํธ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. SafeFileHandle.Type์ ํธ๋ค์ดํ์ผ, ํ์ดํ, ์์ผ, ๋๋ ํฐ๋ฆฌ ๋๋ ๊ธฐํ OS ๊ฐ์ฒด์ธ์ง ์ฌ๋ถ๋ฅผ ๋ณด๊ณ ํฉ๋๋ค(dotnet/runtime #124561). SafeFileHandle.CreateAnonymousPipe๋ ๊ฐ๋๋จ์ ๋น๋๊ธฐ ๋์์ ๋ถ๋ฆฌํ์ฌ ํ์ดํ ์์ ๋ง๋ค ์ ์์ผ๋ฉฐ(dotnet/runtime #125220), RandomAccess. Read/Write๋ ํ์ดํ์ฒ๋ผseek์ด ๋ถ๊ฐ๋ฅํ ํธ๋ค์์๋ ์๋ํฉ๋๋ค(dotnet/runtime #125512). Windows์์๋ ํ๋ก์ธ์ค๊ฐ ๋ฆฌ๋ค์ด๋ ํธ๋stdout/stderr์ ๋ํด ์ค๋ฒ๋ฉ I/O๋ฅผ ์ฌ์ฉํ๊ฒ ๋์ด, ๋ง์ ํ๋ก์ธ์ค๋ฅผ ๋ค๋ฃจ๋ ์ฑ์์ ์ค๋ ๋ ํ ๋ธ๋กํน์ ์ค์ผ ์ ์์ต๋๋ค (dotnet/runtime #125643).
using Microsoft.Win32.SafeHandles;
using System.IO;
SafeFileHandle.CreateAnonymousPipe(out SafeFileHandle readEnd, out SafeFileHandle writeEnd,
asyncReads: true, asyncWrites: false);
Console.WriteLine(readEnd.Type); // Pipe
์ ๊ท์: ๋ชจ๋ ์ ๋์ฝ๋ ์ค๋ฐ๊ฟ ์ํ์ค ์ธ์
์๋ก์ด RegexOptions.AnyNewLine ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ๋ฉด ^, $, .๊ฐ \\n๋ฟ๋ง ์๋๋ผ์ ์ฒด ์ ๋์ฝ๋ ์ค ๋ฐ๊ฟ ๋ฌธ์ ์งํฉ์ ์ค ๋์ผ๋ก ์ทจ๊ธํฉ๋๋ค(dotnet/runtime #124701). ์ด๋ Windows, Unix ๋ฐ ์ ๋์ฝ๋ ํน์ ์ค ๋ฐ๊ฟ์ด ํผํฉ๋ ์ ์๋ ํ
์คํธ๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ ๋ ์ ์ฉํฉ๋๋ค. Preview 3์๋ ์ผ๋ฐ์ ์ธ ์ ๊ท์ ํจํด์ ๋ํ ์ต์ ํ ๊ฐ์ ์ฌํญ๋ ํฌํจ๋์ด ์์ต๋๋ค.
using System.Text.RegularExpressions;
string text = "line1\\r\\nline2\\u0085line3\\u2028line4";
var matches = Regex.Matches(
text,
@"^line\\d$",
RegexOptions.Multiline | RegexOptions.AnyNewLine);
ํธํ์ฑ ํ๊ดด ๋ณ๊ฒฝ ์ฌํญ
-
ZipArchive๋ ์ด์ ํญ๋ชฉ์ ์ฝ๋ ๋์ CRC32๋ฅผ ๊ฒ์ฆํฉ๋๋ค. ์ด์ ์๋ ํต๊ณผ๋๋ ์์๋๊ฑฐ๋ ์๋ฆฐ ์์นด์ด๋ธ๊ฐ ์ด์ InvalidDataException์ ๋ฐ์์ํฌ์ ์์ต๋๋ค(dotnet/runtime #124766). -
์ฒ๋ฆฌ๋์ง ์์
BackgroundService์์ธ๋ ์ด์ ์กฐ์ฉํ ๋ฌด์๋์ง ์๊ณ ํธ์คํธ๋ฅผ ์ค์ง์ํต๋๋ค(dotnet/runtime #124863). -
์๋ฒ์ ํด๋ผ์ด์ธํธ ์ธ์ฆ์ ๊ฒ์ฆ ์ค ์จ๋ผ์ธ AIA(Authority Information Access) ๊ฐ์ ธ์ค๊ธฐ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๋นํ์ฑํ๋์์ต๋๋ค. ์จ๋ผ์ธ AIA ๊ฐ์ ธ์ค๊ธฐ์ ์์กดํ๊ณ ์์๋ค๋ฉด ๊ฒ์ฆ ๊ตฌ์ฑ์ ๋ค์ ํ์ธํ์ญ์์ค(dotnet/runtime #125049).
-
TarWriter๋ ๋์ผํํ๋ ๋งํฌ ํ์ผ์ด ์์นด์ด๋ธ์ ์ฌ๋ฌ ๋ฒ ํฌํจ๋ ๋HardLinkํญ๋ชฉ์ ์ถ๋ ฅํฉ๋๋ค(dotnet/runtime #123874).
๋ฒ๊ทธ ์์ (Bug fixes)
-
์์กด์ฑ ์ฃผ์ (Dependency injection)
- ํฉํ ๋ฆฌ ๊ธฐ๋ฐ ์ํ ์ข
์์ฑ์ ์ด์ ์ ์ฉํ์ง ์์ ์ค๋ฅ ๋์ ๋ช
ํํ
InvalidOperationException์ ๋ฐ์์ํต๋๋ค(dotnet/runtime #124331).
- ํฉํ ๋ฆฌ ๊ธฐ๋ฐ ์ํ ์ข
์์ฑ์ ์ด์ ์ ์ฉํ์ง ์์ ์ค๋ฅ ๋์ ๋ช
ํํ
-
๋ก๊น (Logging)
- ๋ก๊น ์์ค ์์ฑ๊ธฐ๊ฐ ์ด์ ์ ๋ค๋ฆญ ๋ฉ์๋๋ฅผ ์ง์ํฉ๋๋ค(dotnet/runtime #124638).
-
๋คํธ์ํน (Networking)
- Windows์
HttpListener์์ HTTP.sys ์ปค๋ ์๋ต ๋ฒํผ๋ง์ ์ ์ดํ ์ ์์ต๋๋ค(dotnet/runtime #124720).
- Windows์
๋ฐํ์ ์ ๋ฐ์ดํธ
Runtime async: ๋ฏธ๋ฆฌ ๋ณด๊ธฐ API ์ตํธ์ธ ์๊ตฌ ์ฌํญ ์ ๊ฑฐ
Runtime async๋ ์ฌ์ ํ runtime-async=on ๊ธฐ๋ฅ ์ค์์น๋ฅผ ์ฌ์ฉํ์ง๋ง, Preview 3๋ถํฐ๋ API์ ์ ์ฉ๋์๋ [RequiresPreviewFeatures] ๊ฒ์ดํธ๊ฐ ์ ๊ฑฐ๋์์ต๋๋ค. ์ด์ net11.0 ํ๋ก์ ํธ์์ runtime-async=on์ ์ผ๊ธฐ์ํด์๋ง \\<EnablePreviewFeatures>true\\</EnablePreviewFeatures>๋ฅผ ์ค์ ํ ํ์๊ฐ ์์ต๋๋ค(dotnet/runtime #124488).
๋ํ ์ด๋ฒ ํ๋ฆฌ๋ทฐ์๋ NativeAOT ๋ฐ ReadyToRun ์ง์๋ ํฌํจ๋์์ต๋๋ค(dotnet/runtime #123952, dotnet/runtime #124203, dotnet/runtime #125420). ํ์ ์์ ์ผ๋ก continuation ๊ฐ์ฒด๋ฅผ ๋ณด๋ค ์ ๊ทน์ ์ผ๋ก ์ฌ์ฌ์ฉํ๊ณ , ๋ณ๊ฒฝ๋์ง ์์ ๋ก์ปฌ ๊ฐ์ ์ ์ฅํ์ง ์๋๋ก ํ์ฌ async ์ค์ฌ ์ฝ๋์์ ํ ๋น(alloc) ๋ถํ๋ฅผ ์ค์์ต๋๋ค (dotnet/runtime #125556, dotnet/runtime #125615).
<PropertyGroup>
<Features>runtime-async=on</Features>
- <EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>
JIT ์ต์ ํ: switch, ๊ฒฝ๊ณ ๊ฒ์ฌ, ํ ๋ณํ ๊ฐ์
Preview 3๋ ์์ค ์ฝ๋ ๋ณ๊ฒฝ ์์ด๋ ์ผ๋ฐ ์ฝ๋์ ์ด์ ์ ์ ๊ณตํ๋ JIT ๊ฐ์ ์ฌํญ์ ๊ณ์ํด์ ์ ๊ณตํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์ค ๋์ switch ํํ์๊ณผ ๊ฐ์ ์ผ๋ฐ์ ์ธ ํจํด์ด ๋ ๋จ์ํ ๋ถ๊ธฐ ์๋ ๊ฒ์ฌ ํํ๋ก ์ ํ์ง๋ฉฐ(dotnet/runtime #124567), ์ธ๋ฑ์ค-from-end ์ ๊ทผ ๋ฐฉ์์์ ๋ถํ์ํ ๊ฒฝ๊ณ ๊ฒ์ฌ๋ฅผ ๋ ๋ง์ด ์ ๊ฑฐํ ์ ์๊ฒ ๋์์ผ๋ฉฐ(dotnet/runtime #124571), AVX-512 ์ด์ ์ x86 ํ๋์จ์ด์์ uint โ float/double ํ ๋ณํ์ด ๋ ๋นจ๋ผ์ก์ต๋๋ค(dotnet/runtime #124114).
์ปดํ์ผ๋ฌ ์ธก์ ์ง์ ์์ ์ ํตํด JIT๊ฐ ์ด๋ฌํ ์ถ์ฝ์ ๋ ๋ง์ ์ค์ ์ฝ๋์ ์ ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค.
bool isSmall = x is 0 or 1 or 2 or 3 or 4;
int tail = values[^1] + values[^2];
double d = someUint;
๋ธ๋ผ์ฐ์ ๋ฐ WebAssembly: WebCIL ๋ฐ ๋๋ฒ๊น ๊ฐ์
Preview 3๋ WebCIL ํ์ด๋ก๋ ๋ก๋ฉ ์ง์์ ํฌํจํ์ฌ ๋ธ๋ผ์ฐ์ /CoreCLR ์์
์ ํ์ฅํ์ผ๋ฉฐ(dotnet/runtime #124758, dotnet/runtime #124904), ๋๋ฒ๊น
์ ์ํ ์ฌ๋ณผ ๋ฐ ์คํ ํธ๋ ์ด์ค ํ์ง์ ๊ฐ์ ํ์ผ๋ฉฐ(dotnet/runtime #124500, dotnet/runtime #124483), JS ๊ฒฝ๊ณ๋ฅผ ๋์ด float[], Span<float>, ArraySegment<float>๋ฅผ ๋ ์ง์ ์ ์ผ๋ก ๋ง์ฌ๋งํ ์ ์๊ฒ ํ์ต๋๋ค(dotnet/runtime #123642).
ํธํ์ฑ ๊นจ๋ ๋ณ๊ฒฝ ์ฌํญ (Breaking changes)
- NativeAOT ๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๋ ฅ์ ์ด์ Unix์์ ๊ด๋ก์ ์ธ
lib์ ๋์ฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์คํฌ๋ฆฝํธ๊ฐMyLib.so๋ฅผ ๊ธฐ๋ํ๋ค๋ฉดlibMyLib.so๋ฅผ ์ฐพ๋๋ก์์ ํ์ธ์ (dotnet/runtime #124611).
๋ฒ๊ทธ ์์ (Bug fixes)
-
JIT
- async save/restore, if-conversion, return-block ๋ณต์ ๊ด๋ จ ์ ํ์ฑ ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค(dotnet/runtime #125044, dotnet/runtime #125072, dotnet/runtime #124642).
-
VM / ๋ฐํ์ ๋น๋๊ธฐ
- runtime-async ์ฌ๊ฐ(resumption) ์คํ ์ ๊ฒฝํฉ ๋์(race leak)์, ๊ฒฝํฉ ์ ๊ต์ฐฉ ์ํ๊ฐ ๋ฐ์ํ ์ ์๋ ์ ๊ธ(lock) ์์ค ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค (dotnet/runtime #125407, dotnet/runtime #125675).
SDK ์ ๋ฐ์ดํธ
CLI์์ ์๋ฃจ์ ํํฐ๋ฅผ ํธ์งํ ์ ์์ต๋๋ค.
dotnet sln ๋ช
๋ น์ ์ฌ์ฉํ์ฌ CLI์์ ์ง์ ์๋ฃจ์
ํํฐ(.slnf)๋ฅผ ์์ฑํ๊ณ ํธ์งํ ์ ์๊ฒ ๋์์ต๋๋ค(dotnet/sdk #51156). ์ด๋ฅผ ํตํด ๋๊ท๋ชจ ๋ฆฌํฌ์งํ ๋ฆฌ์์ ์ฃผ ์๋ฃจ์
์ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์ผ๋ถ ํ๋ก์ ํธ๋ง ๋ก๋ํ๊ฑฐ๋ ๋น๋ํ ์ ์์ต๋๋ค. ์๋ฃจ์
ํํฐ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ฌธ์์์ ํ์ธํ ์ ์์ต๋๋ค.
dotnet new slnf --name MyApp.slnf
dotnet sln MyApp.slnf add src/Lib/Lib.csproj
dotnet sln MyApp.slnf list
dotnet sln MyApp.slnf remove src/Lib/Lib.csproj
ํ์ผ ๊ธฐ๋ฐ ์ฑ์ ์ฌ๋ฌ ํ์ผ๋ก ๋ถ๋ฆฌํ ์ ์์ต๋๋ค
ํ์ผ ๊ธฐ๋ฐ ์ฑ์ด ์ด์ #:include๋ฅผ ์ง์ํ๋ฏ๋ก, ํ์ผ ๊ธฐ๋ฐ ์ํฌํ๋ก๋ฅผ ์ ์งํ ์ฑ๋ก ๊ณต์ฉ ํฌํผ๋ฅผ ๋ณ๋์ ํ์ผ๋ก ๋ถ๋ฆฌํ ์ ์์ต๋๋ค(dotnet/sdk #52347). Roslyn์ ํด๋น ์ง์๋ฌธ์ ๋ํ ํธ์ง๊ธฐ ์๋ ์์ฑ ๊ธฐ๋ฅ๋ ์ถ๊ฐํ์ต๋๋ค(dotnet/roslyn #82625).
#:include helpers.cs
#:include models/customer.cs
Console.WriteLine(Helpers.FormatOutput(new Customer()));
dotnet run-e๋ฅผ ์ฌ์ฉํ์ฌ ๋ช
๋ น์ค์์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค
dotnet run -e FOO=BAR๋ฅผ ์ฌ์ฉํ๋ฉด๋ก์ปฌ ์ฑ ์คํ ์ ์
ธ ์ํ๋ฅผ ๋ด๋ณด๋ด๊ฑฐ๋ ๋ฐ์น ํ๋กํ์ ์์ ํ์ง ์๊ณ ๋ ๋ช
๋ น์ค์์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค(dotnet/sdk #52664). ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ๋จํ ์ค์ ์ฌ์ ์ ์ฌํญ์ ์
ธ ์ํ๋ ๋ฐ์น ์ค์ ๋์ ๋ช
๋ น์ค์ ์ ์งํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ์์ผ๋ก ์ ๋ฌ๋ ํ๊ฒฝ ๋ณ์๋ MSBuild ๋ก์ง์์ ์ฒ๋ฆฌํ ์ ์๋๋ก RuntimeEnvironmentVariable ํญ๋ชฉ์ผ๋ก ์ ๊ณต๋ฉ๋๋ค.
dotnet run -e ASPNETCORE_ENVIRONMENT=Development -e LOG_LEVEL=Debug
dotnetwatch์ Aspire, ํฌ๋์ ๋ณต๊ตฌ ๋ฐ Windows ๋ฐ์คํฌํฑ ๊ฐ์ ์ฌํญ์ด ์ถ๊ฐ๋์์ต๋๋ค.
Preview 3์๋ ์ฅ์๊ฐ ๋ก์ปฌ ๊ฐ๋ฐ ๋ฃจํ๋ฅผ ์ํ ์ฌ๋ฌ dotnet watch ์
๋ฐ์ดํธ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. Aspire ์ฑ ํธ์คํธ์ ์ฐ๋ํ ์ ์๊ณ (dotnet/sdk #53192), ์ถฉ๋ ๋ฐ์ ํ ๊ด๋ จ ํ์ผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ๊ฐ์ง๋๋ฉด ์๋์ผ๋ก ๋ค์ ์คํํ๋ฉฐ(dotnet/sdk #53314), WinForms ๋ฐ WPF์ ๊ฐ์ Windows ๋ฐ์คํฌํฑ ์ฑ์์ Ctrl+C ์ฒ๋ฆฌ๋ฅผ ๋ ์ํํ๊ฒ ํฉ๋๋ค(dotnet/sdk #53127).
๊ธฐํ CLI ๊ฐ์ ์ฌํญ
-
dotnet format์ ์ด์ ๋ค์ค ๋์ ํ๋ก์ ํธ์ ๋ํด-framework์ ์ง์ํฉ๋๋ค(dotnet/sdk #53202). -
MTP
๋ชจ๋์ dotnet test๋ ์ด์ -artifacts-path๋ฅผ ์ง์ํฉ๋๋ค(dotnet/sdk #53353). -
dotnet toolexec ๋ฐ dnx๊ฐ ๋์ด์ ์ถ๊ฐ ์น์ธ ํ๋กฌํํธ๋ก ์ธํด ์ค์ง๋์ง ์์ต๋๋ค(dotnet/sdk #52956).
๋ฒ๊ทธ ์์
-
๊ธ๋ก๋ฒ ๋ฐ ๋ก์ปฌ ๋๊ตฌ์
๋ํด dotnet tool install --source๊ฐ ์ ์ฉ๋์ง์๋ ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค(dotnet/sdk #52787). -
dotnet remove package๊ฐ project์ธ์๋ฅผ ์ธ์ํ์ง ๋ชปํ๋ ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค(dotnet/sdk #53401). -
dotnet run์ด ์๋ก๋ค๋ฅธ ๋์ ํ๋ ์์ํฌ๋ฅผ ์ฐธ์กฐํ๋ ํ๋ก์ ํธ๋ฅผ ๋์์ผ๋ก ํ ๋๋ฐ์ํ๋ NETSDK1005 ์ค๋ฅ๋ฅผ์์ ํ์ต๋๋ค(dotnet/sdk #53523). -
dotnet workload repair๋ ํ์์ด์๋ชป๋์๊ฑฐ๋ ์์๋ ์ํฌ๋ก๋ ์ธํธ๋ฅผ ๋ณต๊ตฌํ ์ ์์ต๋๋ค(dotnet/sdk #52434). -
-self-contained ์ต์ ์ด๋ ์ด์ํญ์ true๋ฅผ ์๋ฏธํ์ง์๊ณ , ์ ๋ฌ๋ ๊ฐ์ ๊ตฌ๋ฌธ ๋ถ์ํฉ๋๋ค(dotnet/sdk #52333).
C# ํ๋ก๊ทธ๋๋ฐ ์ธ์ด
์ ๋์จ(union) ์ ํ ์ง์
Preview2์์ ์ ๋์จ ์ ํ์ ๋ํ ์ปดํ์ผ๋ฌ ์ง์์ด ์ถ๊ฐ๋์์ต๋๋ค. Preview 3์์๋ ์ ๋์จ ์ ํ์ ๋ค๋ฃฐ ๋์ IDE ์ง์์ด ๋์ฑ ๊ฐ์ ๋์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ์ ๋์จ ์ ํ์ ๋ํ ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ๊ณผ C# ๊ฐ์ด๋์์ ํ์ธํ ์ ์์ต๋๋ค. โ์๋ก์ด ๊ธฐ๋ฅโ ํ์ด์ง์๋ ์ธ์ด ์ฐธ์กฐ ๋งํฌ๊ฐ ํฌํจ๋์ด ์์ผ๋ฉฐ, ์กฐ๋ง๊ฐ ํํ ๋ฆฌ์ผ ๋ฑ ์ถ๊ฐ ์๋ฃ ๋งํฌ๋ ์ถ๊ฐ๋ ์์ ์
๋๋ค.
๋ํ Preview 3์์๋ UnionAttribute ํ์
๊ณผ IUnion ์ธํฐํ์ด์ค์ ๋ํ ํด๋ฆฌํ์ ์ง์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
`namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] public sealed class UnionAttribute : Attribute;
public interface IUnion
{
object? Value { get; }
}
}`
ASP .NET Core
Zstandard ์๋ต ์์ถ ๋ฐ ์์ฒญ ์์ถ ํด์
ASP.NET Core๋ ์๋ต ์์ถ๊ณผ ์์ฒญ ์์ถ ํด์ ๋ชจ๋์์ Zstandard(zstd)๋ฅผ ์ง์ํฉ๋๋ค(dotnet/aspnetcore #65479). ๊ธฐ์กด์ response-compression ๋ฐ request-decompression ๋ฏธ๋ค์จ์ด์ zstd ์ง์์ด ์ถ๊ฐ๋์์ผ๋ฉฐ, ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋ฉ๋๋ค.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCompression();
builder.Services.AddRequestDecompression();
builder.Services.Configure<ZstandardCompressionProviderOptions>(options =>
{
options.CompressionOptions = new ZstandardCompressionOptions
{
Quality = 6 // 1-22, ๋์์๋ก ๋ ์ ์์ถ๋์ง๋ง ๋๋ ค์ง๋๋ค
};
});
์ด ๊ธฐ์ฌ์ ๋ํด @manandre ๋๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
Virtualize: ๋ฐํ์์์ ๋์ด ๊ฐ๋ณ ํญ๋ชฉ์ ์ ์
Blazor์ Virtualize<TItem> ์ปดํฌ๋ํธ๋ ๋ ์ด์ ๋ชจ๋ ํญ๋ชฉ์ ๋์ด๊ฐ ๋์ผํ๋ค๊ณ ๊ฐ์ ํ์ง ์์ต๋๋ค. ์ด์ ๋ฐํ์์์ ์ธก์ ๋ ํญ๋ชฉ ํฌ๊ธฐ์ ๋ง์ถฐ ์ ์ํ๋ฏ๋ก, ํญ๋ชฉ ๋์ด๊ฐ ๋ค์ํ ๊ฒฝ์ฐ์๋ ์๋ชป๋ ์ฌ๋ฐฑ ๋ฐ ์คํฌ๋กค ๋ฌธ์ ๋ฅผ ์ค์
๋๋ค. ๋ํ ํ๊ท ํญ๋ชฉ ๋์ด ๊ณ์ฐ์ ์ ํ๋๋ฅผ ๋์ด๊ธฐ ์ํด OverscanCount์ ๊ธฐ๋ณธ๊ฐ์ด 3์์ 15๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค. ์ ์ฌ์ ์ธ ์ฑ๋ฅ ์ํฅ ๊ฐ๋ฅ์ฑ์ ์ค์ด๊ธฐ ์ํด QuickGrid๋ OverscanCount๋ฅผ ๊ณ์ 3์ผ๋ก ์ ์งํฉ๋๋ค(dotnet/aspnetcore #64964).
<Virtualize Items="messages" Context="message">
<article class="message-card">
<h4>@message.Author</h4>
<p>@message.Text</p>
</article>
</Virtualize>
HTTP/3: ๋ ์ด๋ฅธ ์์ ์ ์์ฒญ ์ฒ๋ฆฌ ์์
Kestrel์ ์ด์ ์ ์ด ์คํธ๋ฆผ๊ณผ SETTINGS ํ๋ ์์ ๋จผ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ HTTP/3 ์์ฒญ ์ฒ๋ฆฌ๋ฅผ ์์ํ๋ฏ๋ก, ์ ์ฐ๊ฒฐ์์ ์ฒซ ๋ฒ์งธ ์์ฒญ์ ์ง์ฐ ์๊ฐ์ ์ค์ ๋๋ค(dotnet/aspnetcore #65399).
๋ฒ๊ทธ ์์ (Bug fixes)
-
Blazor
-
Virtualize์์ null์ฐธ์กฐ ์ค๋ฅ๋ฅผ ์์ ํ์ต๋๋ค(dotnet/aspnetcore #65207). -
overflow-x๊ฐ ์ค์ ๋๊ฒฝ์ฐ์ scroll-container ๊ฐ์ง๋ฅผ ์์ ํ์ต๋๋ค(dotnet/aspnetcore #65744). -
๊ฒ์๋ Blazor WebAssembly ์ฑ์์ Web Worker ํ ํ๋ฆฟ ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค(dotnet/aspnetcore #65885).
-
TempData ์ง์ฐ ๋ก๋ฉ ์์ :
Get,Remove,Keep๋ฐ ์ด๊ฑฐ(enumeration) ๋์์ด ์ด์ ์ง์ฐ ๋ก๋ฉ์ ์ฌ๋ฐ๋ฅด๊ฒ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค (dotnet/aspnetcore #65722). -
ResourceCollectionProvider์์IJSObjectReference๋์๋ฅผ ์์ ํ์ต๋๋ค(dotnet/aspnetcore #65606). -
Blazor ๋ฆฌ์์ค ์ปฌ๋ ์ ์๋ํฌ์ธํธ์ ์บ์ ํค๋์
no-transform์ด ํฌํจ๋๋๋กํ๊ณ ,Varyํค๋๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์์ ํ์ต๋๋ค(dotnet/aspnetcore #65513).
-
-
๋ฐ์ดํฐ ๋ณดํธ
- .NET Framework ๋์์์
ManagedAuthenticatedEncryptorํด์ ๊ณ์ฐ ๋ฐ ๋น๊ต ๋์์ ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65890).
- .NET Framework ๋์์์
-
HTTP / Kestrel
-
HTTP/2 HEADERS ํ๋ ์์ ํจ๋ฉ ๊ธธ์ด ๊ฒ์ฆ์ด PRIORITY ํ๋๊ทธ ๋ฐ์ดํธ๋ฅผ ๊ณ ๋ คํ๋๋ก ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65729).
-
CONTINUATION ํ๋ ์์ ๊ฑธ์ณ ํธ๋ ์ผ๋ฌ๊ฐ ๋ถํ ๋ ๋ ๋ฐ์ํ๋ HTTP/2 Content-Length ๋ถ์ผ์น๋ฅผ ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65765).
-
HPACK/QPACK ๋์ฝ๋๊ฐ
MaxRequestHeaderFieldSize๋ฌธ์์ ๋ฐ๋ผ ๋น์์ถ ํค๋ ํฌ๊ธฐ ์ ํ์ ๊ฒ์ฆํ๋๋ก ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65771). -
RFC 8446์ ๋ฐ๋ผ
TlsListener์์ ์ง๋์น๊ฒํฐ TLS ๋ ์ฝ๋ ๊ธธ์ด๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ์์ ํ์ต๋๋ค(dotnet/aspnetcore #65558). -
HTTP ์๋ต์ ๋ํ
ReasonPhrase๊ฒ์ฆ์ ์ ๋ฐ์ดํธํ์ต๋๋ค (dotnet/aspnetcore #65797).
-
-
JSON ํจ์น
- ๋ฐฐ์ด ์์ ๋ด๋ถ ์์ฑ์ ๋ํ
JsonPatchDocument์์ ์ ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65470).
- ๋ฐฐ์ด ์์ ๋ด๋ถ ์์ฑ์ ๋ํ
-
๋ฏธ๋ค์จ์ด
- ์์ฒญ์ด ์บ์ ์ฐ๊ธฐ์ ๊ฐ์ ํฑ์ ๋๋ฌํ์ ๋ ์บ์๋ ํญ๋ชฉ์ ์๋ชป ๊ฑฐ๋ถํ๋ ์ถ๋ ฅ ์บ์ฑ ์ ์ ๋ ํ์ธ์ ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65659).
-
์ต์ API
JsonElement,Dictionary์ ๊ฐ์ด ์ธ๋ฑ์๊ฐ์๋ ์ ํ์ ๋ง๋ฌ์ ๋ ๊ฒ์ฆ ์์ค ์์ฑ๊ธฐ๊ฐ ์ถฉ๋ํ๋ ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65432).
-
SignalR
StatefulReconnect์์ ์ทจ์์ฒ๋ฆฌ(cancellation handling)๊ฐ ๋ ์ ๊ทน์ ์ผ๋ก ์๋ํ๋๋ก ์์ ํ์ต๋๋ค (dotnet/aspnetcore #65732).
MAUI
Maps: ํด๋ฌ์คํฐ๋ง, ์คํ์ผ๋ง, ๋์ฑ ํ๋ถํ ์ํธ์์ฉ API ์ถ๊ฐ
Preview 3์์ Map ์ปจํธ๋กค์ ๋๊ท๋ชจ ๊ธฐ๋ฅ ํ์ฅ์ ๊ฑฐ์ณค์ต๋๋ค. ํ ํด๋ฌ์คํฐ๋ง, ์ฌ์ฉ์ ์ง์ ํ ์์ด์ฝ, ์ฌ์ฉ์ ์ง์ JSON ์คํ์ผ๋ง, MapLongClicked, ์ยท๋ค๊ฐํยทํด๋ฆฌ๋ผ์ธ ํด๋ฆญ ์ด๋ฒคํธ, MapElement.IsVisible ๋ฐ ZIndex, ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ ๋ณด ์ฐฝ ์ ์ด, ๋ ๋ถ๋๋ฌ์ด ์์ญ ๋ณ๊ฒฝ, ๋ ํ๋ถํ ์ฌ์ฉ์ ์์น ์ด๋ฒคํธ๊ฐ ํฌํจ๋ฉ๋๋ค (dotnet/maui #29101, dotnet/maui #33831, dotnet/maui #33950, dotnet/maui #33982, dotnet/maui #33985, dotnet/maui #33792, dotnet/maui #33799, dotnet/maui #33991, dotnet/maui #33993). ์ด API ๋๋ถ์ ํ๋ซํผ๋ณ ๊ตฌํ์ผ๋ก ๋๋์๊ฐ์ง ์๊ณ ๋ ๊ณ ๋ฐ๋์ด๋ฉฐ ์ธํฐ๋ํฐ๋ธํ ์ง๋ ๊ฒฝํ์ ๋ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
<maps:Map IsClusteringEnabled="True"
MapLongClicked="OnMapLongClicked">
<maps:Pin Label="Seattle"
Location="47.6062,-122.3321"
ClusteringIdentifier="stores"
ImageSource="store.png" />
</maps:Map>
XAML ๋ฐ ์คํ์ผ๋ง ๊ฐ์ : ์์ ์ ์์ ๊ฐ์ ๋ฐ ๋ฐ๋ณต ์๋ ํฅ์
XAML ์์ค ์์ฑ์ด ์ด์ ResourceDictionary ํญ๋ชฉ์ ํฉํ ๋ฆฌ๋ก ๋ฑ๋กํ๊ณ , ํ์ด์ง ์์ ์ ๋ชจ๋ ์คํ์ผ๊ณผ ๋ธ๋ฌ์๋ฅผ ์ฆ์ ์์ฑํ๋ ๋์ ํ์ํ ๋(on demand) ๋ก๋ํ๋๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค(dotnet/maui #33826). ๋ํ Preview 3์์๋ ์์์ XAML ๋ค์์คํ์ด์ค ์ ์ธ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์์ผ๋ฉฐ, Hot Reload ๋๋ ๋์ UI ์
๋ฐ์ดํธ ์ค์ ๋ณ๊ฒฝ๋ ์คํ์ผ๊ณผ ์๊ฐ์ ์ํ๋ฅผ ๋ค์ ์ ์ฉํ ์ ์๋ ๋ช
์์ API๊ฐ ์ถ๊ฐ๋์์ต๋๋ค. ์ฑ์ด ์คํ์ผ์ํธ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ MAUI CSS๋ฅผ ํธ๋ฆฌ๋ฐํ์ฌ ๋ถํ์ํ ์ฑ ํฌ๊ธฐ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค(dotnet/maui #33834, dotnet/maui #34723, dotnet/maui #33160).
ํนํ,InvalidateStyle()๋ฐ VisualStateManager.InvalidateVisualStates()๋ ํด๋ง ๋ฐ ์ฑ ์ฝ๋์์ ์์ ํธ๋ฆฌ๋ฅผ ๋ค์ ์์ฑํ์ง ์๊ณ ๋ ์ธํ๋ ์ด์ค ์คํ์ผ ๋ฐ ์๊ฐ์ ์ํ ๋ณ๊ฒฝ ์ฌํญ์ ๋ค์ ์ ์ฉํ ์ ์๋ ๋ช
์์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
<ContentPage.Resources>
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
<Setter Property="Padding" Value="12,8" />
</Style>
</ContentPage.Resources>
LongPressGestureRecognizer๊ฐ ์ด์ .NET MAUI์ ๋ด์ฅ๋์์ต๋๋ค
.NET MAUI์๋ ์ด์ ํ๋ซํผ ์ ๋ฐ์ ๊ฑธ์ณ ์ง์ ์๊ฐ, ์ด๋ ์๊ณ๊ฐ, ์ํ ๋ณ๊ฒฝ ๋ฐ ๋ช
๋ น์ ์ง์ํ๋๋ด์ฅ LongPressGestureRecognizer๊ฐํฌํจ๋์ด ์์ต๋๋ค(dotnet/maui #33432). ์ด๋ฅผ ํตํด ํดํท ๋์์ด๋ ์ฌ์ฉ์ ์ง์ ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ํ์ ์์ด ๊ธธ๊ฒ ๋๋ฅด๊ธฐ ์ํธ ์์ฉ์ ๋ํ ๊ธฐ๋ณธ API๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
<Image Source="avatar.png">
<Image.GestureRecognizers>
<LongPressGestureRecognizer
MinimumPressDuration="750"
Command="{Binding ShowContextMenuCommand}" />
</Image.GestureRecognizers>
</Image>
ํ๋ซํผ ํตํฉ์ ํตํ iOS ์๋ฆผ ๊ถํ ์ง์ ์ถ๊ฐ
Preview 3์๋iOS์ PostNotifications ๊ถํ๊ตฌํ์ด ์ถ๊ฐ๋์ด, ์ฑ์ด ํ๋ซํผ๋ณ ์ฝ๋๋ก ์ ํํ์ง ์๊ณ ๋ ํฌ๋ก์ค ํ๋ซํผ Permissions API๋ฅผ ํตํด ์๋ฆผ ๊ถํ์ ์์ฒญํ ์ ์์ต๋๋ค(dotnet/maui #30132).
var status = await Permissions.RequestAsync<Permissions.PostNotifications>();
.NET for Android, Android 17 / API 37 ํ๋ฆฌ๋ทฐ ์ง์ ์ถ๊ฐ
.NET for Android Preview 3์ Android 17 / API 37 ํ๋ฆฌ๋ทฐ์ ํธํ๋๋ฏ๋ก, ์ฑ์ ๊ณง ์ถ์๋ ํ๋ซํผ์ ๋ํด ๋ฏธ๋ฆฌ ๊ฒ์ฆํ ์ ์์ต๋๋ค.
.NET 11 Preview 3 ์ถ์๋ฅผ ์ค๋นํ๋ ๊ณผ์ ์์ .NET MAUI ํ๊ณผ ๊ธด๋ฐํ ํ๋ ฅํด์ค Uno Platform ํ์๊น์ ๊ฐ์ฌ๋ฅผ ๋๋ฆฝ๋๋ค. ๊ทธ๋ค์ ๊ธฐ์ฌ ๋๋ถ์ .NET for Android๊ฐ Google์ ์ต์ ํ๋ซํผ ์ ๋ฐ์ดํธ์ ์๋ฒฝํ๊ฒ ํธํ๋์ด, ๊ฐ๋ฐ์๋ค์ด Android 17 ํ๋ฆฌ๋ทฐ ๋ฐ API 37์ ์ฆ์ ํ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค. ์ด๋ฌํ ํํธ๋์ญ์ .NET ์ํ๊ณ๋ฅผ ๊ฐํํ๊ณ , ๊ณ ํ์ง์ ํฌ๋ก์ค ํ๋ซํผ ๊ฐ๋ฐ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ค๋ ์ฐ๋ฆฌ์ ๊ณต๋ ์์ง๋ฅผ ๋ฐ์ํฉ๋๋ค.
API 37์ ์ฌ์ฉํ๋ ค๋ฉด.csproj ํ์ผ์ ์
๋ฐ์ดํธํ์ธ์:
<PropertyGroup>
<TargetFramework>net11.0-android37</TargetFramework>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>
Visual Studio์์ API 37์์ค์นํ๋ ค๋ฉด ๋๊ตฌ > Android > Android SDK ๊ด๋ฆฌ์ > ์ ์ฅ์ > ์ ์ฒด ๋ชฉ๋ก์ ์ฌ์ฉํ์ญ์์ค:
์ฐธ๊ณ
๊ธฐ๋ณธ์ ์ผ๋ก SDK๊ด๋ฆฌ์๋ C:\\Program Files (x86)\\Android\\android-sdk\\platforms\\android-37.0์ ์ค์น๋๋ฉฐ, .NET for Android๋ ์ด ๊ฒฝ๋ก๋ฅผ ์๋์ผ๋ก ์ฐพ์ง ๋ชปํฉ๋๋ค. ํฅํ ๋ฆด๋ฆฌ์ค์์ ์ด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ์์ ํด๊ฒฐ์ฑ
์ผ๋ก ํด๋์ด๋ฆ์ C:\\Program Files (x86)\\Android\\android-sdk\\platforms\\android-37๋ก ๋ณ๊ฒฝํ์ญ์์ค.
Android 17์์ ์ฌ์ฉํ ์ ์๋ ์๋ก์ด API๋ฅผ ํธ์ถํ๋ ์ ์ฒด์์ ๋ API-37 HPKE ์ํธํ ์ํ์ ์ฐธ์กฐํ์ญ์์ค. ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฒด ๋ชฉ๋ก์.NET for Android Preview 3 ๋ฆด๋ฆฌ์ค ๋ ธํธ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
.NET for Android์ CLI ๊ธฐ๋ฐ ๊ธฐ๊ธฐ ๊ฒ์ ๋ฐ ๋ฐฐํฌ ํ๋ฆ ๊ฐ์
์ด์ dotnet run์ ์ฌ์ฉํ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์๋ฎฌ๋ ์ดํฐ๋ฅผ ๋์ดํ๊ณ ๋ฐฐํฌ ์ ์ ์ ํํ AVD๋ฅผ ์๋์ผ๋ก ๋ถํ
ํ ์ ์์ต๋๋ค(dotnet/android #10826). ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ผ๋ก ์ธํด CLI ์ฐ์ Android ๊ฐ๋ฐ์ด IDE ์ ์ฉ ์ฅ์น ๊ด๋ฆฌ์ ๋ ์์กดํ๊ฒ ๋์์ต๋๋ค.
Apple ์ํฌ๋ก๋์ฉ .NET, ํจํค์ง ๋ฐ ๋ฐ์ธ๋ฉ ํ์ง ๊ฐ์
Preview 3์ ํ์ฒ๋ฆฌ ๊ณผ์ ์์ ์ ์ ํ๋ ์์ํฌ๋ฅผ ํํฐ๋งํ์ฌ ์ฑ ๋ฒ๋ค์ ์ค์ ๋ก ํฌํจ๋ ํ๋ ์์ํฌ์ ๋ํด์๋ง ์คํธ๋ฆฌํ ๋ฐ ์ฌ๋ณผ ์ฒ๋ฆฌ๊ฐ ์ด๋ฃจ์ด์ง๋๋ก ํจ์ผ๋ก์จ Apple ์ํฌ๋ก๋ ํจํค์ง์ ๊ฐ์ ํ์ต๋๋ค(dotnet/macios #24845). ๋ฆด๋ฆฌ์ค๋ธ๋์น์๋ NSArray API์๋ํ nullability ์ด๋
ธํ
์ด์
๊ฐ์ ๊ณผ ๊ฐ์ ๋ฐ์ธ๋ฉ ํ์ง ๊ด๋ จ ์์
๋ ํฌํจ๋์ด ์์ต๋๋ค(dotnet/macios #24907).
Apple์ฉ .NET์ Xcode 26.3 ์ง์
์ด์ Apple ํ๋ซํผ์ ๋์์ผ๋ก ํ ๋ Xcode 26.3์ด ์ง์๋ฉ๋๋ค. ์๋ก์ด API๋ ๋์ ๋์ง ์์์ต๋๋ค.
Apple ํ๋ซํผ์ CoreCLR ๊ฐ์ ์ฌํญ
์ด ํ๋ฆฌ๋ทฐ์๋ ๋ชจ๋ Apple ํ๋ซํผ(iOS, macOS, Mac Catalyst ๋ฐ tvOS)์ ๊ฑธ์น ์ฌ๋ฌ CoreCLR ๊ฐ์ ์ฌํญ์ด ํฌํจ๋์ด ์์ต๋๋ค:
-
๋ ์์์ง ๋ฆด๋ฆฌ์ค ๋น๋. ๋ค์ดํฐ๋ธ ์ฌ๋ณผ ์ ๊ฑฐ ๊ธฐ๋ฅ์ด ์ด์ CoreCLR ๋ฐ ReadyToRun(R2R) ํ๋ ์์ํฌ๊น์ง ์ ์ฉ๋์ด, MAUI ํ ํ๋ฆฟ ์ฑ์ ๋ฒ๋ค ํฌ๊ธฐ๊ฐ 77.8MB์์ 41.6MB๋ก ์ค์์ต๋๋ค(dotnet/macios #24678).
-
๋ ๋น ๋ฅธ ์ฆ๋ถ ๋น๋. ์ฌ์ฉ์ ์ด์ ๋ธ๋ฆฌ๋ง ๋ณ๊ฒฝ๋ ๋ R2R ๋ณตํฉ ์ด๋ฏธ์ง๊ฐ ์บ์๋์ด ์ฆ๋ถ ๋น๋ ์๊ฐ์ด ์ฝ 39์ด์์ ์ฝ 26์ด๋ก ๋จ์ถ๋์์ต๋๋ค(dotnet/macios #24735).
-
๋ ์ค๋งํธํ ์ฝ๋ ์์ฑ. R2R ์ปดํ์ผ๋ฌ๋ ์ด์ ๋ฐฐํฌ ๋์์ ํ์ํ ์ต์ ๋ช ๋ น์ด ์ธํธ(์: iOS 16+์ ๊ฒฝ์ฐ ARMv8.2-A)๋ฅผ ๋์์ผ๋ก ํ์ฌ, ๊ธฐ๊ธฐ ํธํ์ฑ์ ์ ํดํ์ง ์์ผ๋ฉด์ ๋ ์ฐ์ํ ๋ค์ดํฐ๋ธ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค(dotnet/macios #24621).
-
macOS์์์ R2R. ReadyToRun ์ปดํ์ผ์ด ์ด์ macOS์์ ์๋ํ๋ฉฐ, ๋ชจ๋ Apple ํ๋ซํผ์ ๋ํ R2R ์ง์์ด ์๋ฃ๋์์ต๋๋ค(dotnet/macios #25080).
Entity Framework Core
ChangeTracker.GetEntriesForState()๋๋ถํ์ํ ๋ณ๊ฒฝ ๊ฐ์ง๋ฅผ ๋ฐฉ์งํฉ๋๋ค
ChangeTracker์์๋ก์ดGetEntriesForState()API๋ ๋จผ์ DetectChanges()๋ฅผ ๊ฐ์ ๋ก ์คํํ์ง ์๊ณ ๋ ์ ํ๋ ์ํ์ ์ถ์ ๋ ์ํฐํฐ๋ฅผ ๋ฐํํฉ๋๋ค(dotnet/efcore #37847). ์ด๋ฅผ ํตํด ๊ด์ฌ ์๋ ์ํ๋ฅผ ์ด๋ฏธ ์๊ณ ์๋ ์ฅ๊ธฐ ์ปจํ
์คํธ๋ ๋๋์ ๋ณ๊ฒฝ ์ถ์ ์ฝ๋์์ ๋ถํ์ํDetectChanges()ํธ์ถ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
var modified = context.ChangeTracker.GetEntriesForState(
added: false,
modified: true,
deleted: false,
unchanged: false);
DbContext ๊ตฌ์ฑ์ ํตํด ์ ๊ณต์๋ฅผ ์ ๊ฑฐํ๊ณ ํ๋ง๋ ํฉํ ๋ฆฌ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค
Preview 3์์๋ ๋ค๋ฅธ ๊ณต๊ธ์๋ฅผ ๋ฑ๋กํ๊ธฐ ์ ์ ์ด์ ๊ณต๊ธ์ ๊ตฌ์ฑ์ ์ ๊ฑฐํ๊ธฐ ์ํRemoveDbContext()/RemoveExtension()ํฌํผ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค(dotnet/efcore #37891). ์ด๋ ํ๋ก๋์
์ฉ SQL Server ๊ตฌ์ฑ์ ๋ฉ๋ชจ๋ฆฌ ๋ด ๋๋ SQLite ๊ณต๊ธ์๋ก ๋์ฒดํ๋ ํ
์คํธ ํ๊ฒฝ์์ ํนํ ์ ์ฉํฉ๋๋ค.
AddPooledDbContextFactory<TContext>()์๋ ์ด์ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์ค๋ฒ๋ก๋๊ฐ ์ถ๊ฐ๋์ด,ConfigureDbContext<TContext>()๋ด์ ์ด๋ฏธ ์กด์ฌํ๋ ๊ตฌ์ฑ์ ๋ํด ๋ ์ด์ ์ถ๊ฐ์ ์ธ ์ค์ ๋ณด์ผ๋ฌํ๋ ์ดํธ๊ฐ ํ์ํ์ง ์์ต๋๋ค(dotnet/efcore #37144).
services.RemoveDbContext<MyContext>();
services.AddPooledDbContextFactory<MyContext>();
๋ง์ด๊ทธ๋ ์ด์ ์ ๋ํ ์ ์ด๋ ฅ ๊ฐํ ๋ฐ ๋ช ํํ ํผ๋๋ฐฑ ์ ๊ณต
์ด์ EF Core์์๋ExcludeForeignKeyFromMigrations(true)๋ฅผ์ฌ์ฉํ์ฌ ๋ง์ด๊ทธ๋ ์ด์
์์ ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ์ ์ธํ ์ ์์ต๋๋ค(dotnet/efcore #37815). ๋ํ ๋ชจ๋ธ ์ค๋
์ท์ ์ต์ ๋ง์ด๊ทธ๋ ์ด์
ID๊ฐ ๊ธฐ๋ก๋๋ฏ๋ก, ํ ์ํฌํ๋ก์์ EF๊ฐ ๋ง์ด๊ทธ๋ ์ด์
ํธ๋ฆฌ์ ๋ถ๊ธฐ๋ฅผ ๋ ์ผ์ฐ ๊ฐ์งํ ์ ์์ต๋๋ค(dotnet/efcore #37689).
modelBuilder.Entity<Order>()
.HasOne(o => o.Customer)
.WithMany(c => c.Orders)
.ExcludeForeignKeyFromMigrations(true);
SQL ์์ฑ ์ ๋ถํ์ํ ์กฐ์ธ์ด ์ ๊ฑฐ๋๊ณ SQL Server์ JSON API๊ฐ ์ถ๊ฐ๋์์ต๋๋ค
1:1 ์กฐ์ธ์ ๋ํ ์ฟผ๋ฆฌ ์์ฑ์ด ์ด์ ์ผ๋ฐ์ ์ธ ์ํฉ์์ ๋ถํ์ํ ์กฐ์ธ์ ์ ๊ฑฐํฉ๋๋ค(dotnet/efcore #37819). SQL Server 2025๋ ์ด์ EF.Functions.JsonContains()๋ฅผ ์ง์ํ๋ฉฐ, ๋ช
ํ์ฑ์ ์ํด ์ด์ ํ๋ฆฌ๋ทฐ API์ ์ด๋ฆ์ดJsonPathExists()๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค(dotnet/efcore #37714,dotnet/efcore #37732).
ํธํ์ฑ ๋ณ๊ฒฝ ์ฌํญ
-
RelationalEventId.MigrationsNotFound๋์ด์ ์ ๋ณด์ฑ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ๋ ๋์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ธ๋ฅผ ๋ฐ์์ํต๋๋ค(dotnet/efcore #37839). -
Microsoft.EntityFrameworkCore.Tools๋ฐMicrosoft.EntityFrameworkCore.Tasks๋๋ ์ด์Microsoft.EntityFrameworkCore.Design์ ์ง์ ์์กดํ์ง ์์ต๋๋ค(dotnet/efcore #37837). -
EFOptimizeContextMSBuild ์์ฑ์ด ์ ๊ฑฐ๋์์ต๋๋ค. ํ๋ก์ ํธ๋ ๋น๋ ํ์ดํ๋ผ์ธ์์ ์ด ์์ฑ์ ์ค์ ํ ๊ฒฝ์ฐ, ์ด๋ฅผ ์ ๊ฑฐํ๊ณ ๋์EFScaffoldModelStage๋ฐEFPrecompileQueriesStage์์ฑ์ ์ฌ์ฉํ์ญ์์ค(dotnet/efcore #37838). -
SqlVector์์ฑ์ ๋ ์ด์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ก๋๋์ง ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฒกํฐ ๊ฐ์ด ํ์ํ ๊ฒฝ์ฐ ๋ช ์์ ์ผ๋ก ํฌ์ํ๊ฑฐ๋ ๋ก๋ํ์ญ์์ค(dotnet/efcore #37829). -
Preview 3์์๋
Microsoft.Data.SqlClient๊ฐ7.0.0์ผ๋ก ์ ๋ฐ์ดํธ๋์์ต๋๋ค. ๊ณต๊ธ์๋ณ SQL Server ๋์์ ์์กดํ๋ ๊ฒฝ์ฐ SqlClient ๋ฆด๋ฆฌ์ค ๋ ธํธ๋ฅผ ๊ฒํ ํ์ญ์์ค(dotnet/efcore #37949).
๋ฒ๊ทธ ์์
-
์์๋๋ ๊ณต๊ธ์ ๊ตฌ์ฑ ์์ด ๊ณต๊ฐํ ๋๋
HierarchyId์ ํ์ด ์ฌ์ฉ๋ ๋ ์ค๋ฅ ๋ณด๊ณ ๊ธฐ๋ฅ์ด ๊ฐ์ ๋์์ต๋๋ค(dotnet/efcore #37733). -
์์ฑ์ ๋ฐฑ์ ํ๋๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ ๋ ๋ช ํํ ์์ธ๋ฅผ ์ถ๊ฐํ์ต๋๋ค(dotnet/efcore #36720).
-
์ค์นผ๋ผ ํฌ์ ๋ฐ nullable-value-type
SetProperty๋๋ค์ ๋ํExecuteUpdate๋ฅผ์์ ํ์ต๋๋ค(dotnet/efcore #37791,dotnet/efcore #37975). -
์ฟผ๋ฆฌ ๋ณํ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์ ์์ ์ฌ๋ฌ JSON ๋ฐ ๋ณตํฉ ์์ฑ ์์ง ์ผ์ด์ค๋ฅผ ์์ ํ์ต๋๋ค(dotnet/efcore #37823,dotnet/efcore #37855,dotnet/efcore #37965).
์ปจํ ์ด๋ ์ด๋ฏธ์ง
.NET ์ปจํ ์ด๋ ์ด๋ฏธ์ง์ ์๋ช ์ ์ฉ
์ด์ ๋ชจ๋ .NET ์ปจํ ์ด๋ ์ด๋ฏธ์ง๋Notary Project์ฌ์์ ๋ฐ๋ผ Microsoft์์ ์ํธํ์ ์ผ๋ก ์๋ช ํฉ๋๋ค.์ด๋ฏธ์ง ์๋ช ์๊ฒ์ฌํ๊ณ ํ์ธํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ต์ ๋ฌธ์๋์ด๋ฏธ์ง ์๋ช ๋ฌธ์๋ฅผ์ฐธ์กฐํ์ญ์์ค.
Notary CLI๋๋ORAS CLI๋ฅผ์ฌ์ฉํ์ฌ ์๋ช ์ํฐํฉํธ์ ๋ํ ์ธ๋ถ ์ ๋ณด๋ฅผ ํ์ธํ์ธ์:
notation inspect mcr.microsoft.com/dotnet/sdk:11.0.100-preview.3 oras discover mcr.microsoft.com/dotnet/sdk:11.0.100-preview.3
