Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions BannerlordModEditor.Common.Tests/Services/ProjectTypeDetectorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Xunit;
using BannerlordModEditor.Common.Services;

namespace BannerlordModEditor.Common.Tests.Services
{
public class ProjectTypeDetectorTests
{
private readonly ProjectTypeDetector _detector;

public ProjectTypeDetectorTests()
{
_detector = new ProjectTypeDetector();
}

[Fact]
public void DetectProjectType_ReturnsUnknownForNonExistentPath()
{
var result = _detector.DetectProjectType("/nonexistent/path");
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hard-coded "/nonexistent/path" is OS/path-format dependent and can make intent less clear on Windows. Prefer generating a guaranteed-nonexistent path under Path.GetTempPath() (e.g., combining a GUID) to keep the test portable and explicit.

Suggested change
var result = _detector.DetectProjectType("/nonexistent/path");
var nonExistentPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
var result = _detector.DetectProjectType(nonExistentPath);

Copilot uses AI. Check for mistakes.
Assert.Equal(ProjectType.Unknown, result.Type);
}

[Fact]
public void DetectProjectType_ReturnsNativeModForSubmoduleOnly()
{
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);

try
{
File.WriteAllText(Path.Combine(tempDir, "SubModule.xml"), "<Module></Module>");

var result = _detector.DetectProjectType(tempDir);
Assert.Equal(ProjectType.NativeMod, result.Type);
Assert.True(result.HasSubmoduleXml);
}
finally
{
Directory.Delete(tempDir, true);
}
}

[Fact]
public void DetectProjectType_ReturnsCustomTemplateForSubmoduleAndCsproj()
{
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);

try
{
File.WriteAllText(Path.Combine(tempDir, "SubModule.xml"), "<Module></Module>");
File.WriteAllText(Path.Combine(tempDir, "TestMod.csproj"), "<Project></Project>");

var result = _detector.DetectProjectType(tempDir);
Assert.Equal(ProjectType.CustomTemplate, result.Type);
Assert.True(result.HasSubmoduleXml);
Assert.True(result.HasCsprojFile);
}
finally
{
Directory.Delete(tempDir, true);
}
}

[Fact]
public void DetectProjectType_ReturnsButrTemplateForButrMarker()
{
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
var butrDir = Path.Combine(tempDir, "BUTR");
Directory.CreateDirectory(butrDir);

try
{
File.WriteAllText(Path.Combine(tempDir, "SubModule.xml"), "<Module></Module>");
File.WriteAllText(Path.Combine(tempDir, "TestMod.csproj"), "<Project></Project>");
File.WriteAllText(Path.Combine(butrDir, "Bannerlord.ButterLib.dll"), "");

var result = _detector.DetectProjectType(tempDir);
Assert.Equal(ProjectType.ButrTemplate, result.Type);
Assert.True(result.HasButrMarker);
}
finally
{
Directory.Delete(tempDir, true);
}
}

[Fact]
public void IsButrTemplateProject_ReturnsTrueForButrProject()
{
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
var butrDir = Path.Combine(tempDir, "BUTR");
Directory.CreateDirectory(butrDir);

try
{
File.WriteAllText(Path.Combine(butrDir, "marker.txt"), "BUTR marker");

var result = _detector.IsButrTemplateProject(tempDir);
Assert.True(result);
}
finally
{
Directory.Delete(tempDir, true);
}
}

[Fact]
public void GetModName_ReturnsCsprojName()
{
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);

try
{
File.WriteAllText(Path.Combine(tempDir, "MyCoolMod.csproj"), "<Project></Project>");

var result = _detector.GetModName(tempDir);
Assert.Equal("MyCoolMod", result);
}
finally
{
Directory.Delete(tempDir, true);
}
}

[Fact]
public void GetModName_ReturnsDirectoryNameWhenNoCsproj()
{
var tempDir = Path.Combine(Path.GetTempPath(), "TestModProject");
Directory.CreateDirectory(tempDir);

try
{
var result = _detector.GetModName(tempDir);
Assert.Equal("TestModProject", result);
Comment on lines +132 to +138
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a fixed temp directory name (TestModProject) risks cross-test/process collisions and can make the test flaky if the directory already exists (or contains leftover files like a .csproj). Use a unique directory name (GUID) like the other tests to ensure isolation.

Suggested change
var tempDir = Path.Combine(Path.GetTempPath(), "TestModProject");
Directory.CreateDirectory(tempDir);
try
{
var result = _detector.GetModName(tempDir);
Assert.Equal("TestModProject", result);
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);
try
{
var result = _detector.GetModName(tempDir);
Assert.Equal(Path.GetFileName(tempDir), result);

Copilot uses AI. Check for mistakes.
}
finally
{
Directory.Delete(tempDir, true);
}
}
}
}
173 changes: 173 additions & 0 deletions BannerlordModEditor.Common/Services/ProjectTypeDetector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace BannerlordModEditor.Common.Services
{
public enum ProjectType
{
Unknown,
ButrTemplate,
CustomTemplate,
NativeMod
}

public class ProjectTypeInfo
{
public ProjectType Type { get; set; }
public string ProjectPath { get; set; } = string.Empty;
public bool HasSubmoduleXml { get; set; }
public bool HasCsprojFile { get; set; }
public bool HasButrMarker { get; set; }
public string? ModName { get; set; }
public string? ModuleDataPath { get; set; }
}

public interface IProjectTypeDetector
{
ProjectTypeInfo DetectProjectType(string projectPath);
bool IsButrTemplateProject(string projectPath);
string? GetModName(string projectPath);
}

public class ProjectTypeDetector : IProjectTypeDetector
{
private static readonly string[] ButrMarkers = new[]
{
"Bannerlord.ButterLib.dll",
"Bannerlord.ButterLib",
"BUTR",
"BUTRLoadingScreen"
};

private static readonly string[] ButrDirectories = new[]
{
"BUTR",
"ButterLib",
"LoadingScreen"
};

public ProjectTypeInfo DetectProjectType(string projectPath)
{
var info = new ProjectTypeInfo
{
ProjectPath = projectPath,
Type = ProjectType.Unknown
};

if (!Directory.Exists(projectPath))
return info;

info.HasSubmoduleXml = File.Exists(Path.Combine(projectPath, "SubModule.xml"));
info.HasCsprojFile = Directory.GetFiles(projectPath, "*.csproj").Any();
info.HasButrMarker = CheckForButrMarkers(projectPath);
info.ModName = GetModName(projectPath);

var moduleDataDir = Path.Combine(projectPath, "ModuleData");
if (Directory.Exists(moduleDataDir))
{
info.ModuleDataPath = moduleDataDir;
}

if (info.HasButrMarker)
{
info.Type = ProjectType.ButrTemplate;
}
else if (info.HasSubmoduleXml && info.HasCsprojFile)
{
info.Type = ProjectType.CustomTemplate;
}
else if (info.HasSubmoduleXml)
{
info.Type = ProjectType.NativeMod;
}

return info;
}

public bool IsButrTemplateProject(string projectPath)
{
return DetectProjectType(projectPath).Type == ProjectType.ButrTemplate;
}

public string? GetModName(string projectPath)
{
if (!Directory.Exists(projectPath))
return null;

var csprojFiles = Directory.GetFiles(projectPath, "*.csproj");
if (csprojFiles.Any())
{
var csprojPath = csprojFiles.First();
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directory.GetFiles(...).First() is not deterministic when multiple .csproj files exist, so GetModName can return different results across machines/filesystems or as files are added. To make this stable and predictable, select deterministically (e.g., sort by name/path), and/or prefer a .csproj matching the directory name, or extract the module name from SubModule.xml when present.

Suggested change
var csprojPath = csprojFiles.First();
var directoryName = new DirectoryInfo(projectPath).Name;
// Prefer a .csproj whose name matches the directory name, otherwise choose deterministically.
var matchingCsproj = csprojFiles.FirstOrDefault(f =>
string.Equals(
Path.GetFileNameWithoutExtension(f),
directoryName,
StringComparison.OrdinalIgnoreCase));
var csprojPath = matchingCsproj ??
csprojFiles
.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)
.First();

Copilot uses AI. Check for mistakes.
var csprojName = Path.GetFileNameWithoutExtension(csprojPath);
return csprojName;
}

var dirName = new DirectoryInfo(projectPath).Name;
return dirName;
}

private bool CheckForButrMarkers(string projectPath)
{
var allFiles = GetAllFiles(projectPath);

foreach (var file in allFiles)
{
var fileName = Path.GetFileName(file);
if (ButrMarkers.Any(marker => fileName.Contains(marker, StringComparison.OrdinalIgnoreCase)))
return true;

var content = SafeReadFile(file);
if (content != null && content.Contains("BUTR", StringComparison.OrdinalIgnoreCase))
return true;
}

var directories = Directory.GetDirectories(projectPath, "*", SearchOption.AllDirectories);
foreach (var dir in directories)
{
var dirName = new DirectoryInfo(dir).Name;
if (ButrDirectories.Any(marker => dirName.Contains(marker, StringComparison.OrdinalIgnoreCase)))
return true;
}

return false;
}
Comment on lines +111 to +135
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckForButrMarkers traverses the directory tree twice (once via GetAllFiles, then again via Directory.GetDirectories(..., AllDirectories)) and attempts to read the full contents of every file. This can become very slow for large repos and can cause significant IO/memory pressure. Consider a single-pass traversal (e.g., using Directory.EnumerateFileSystemEntries/EnumerateFiles + EnumerateDirectories with early-exit) that checks directory names as they’re discovered, and only reads a small, filtered subset of files (by extension and/or max size) when content scanning is needed.

Copilot uses AI. Check for mistakes.

private IEnumerable<string> GetAllFiles(string directory)
{
var files = new List<string>();

try
{
files.AddRange(Directory.GetFiles(directory, "*.*", SearchOption.TopDirectoryOnly));

foreach (var subDir in Directory.GetDirectories(directory))
{
var dirName = new DirectoryInfo(subDir).Name;
if (dirName != "bin" && dirName != "obj" && dirName != ".git")
{
files.AddRange(GetAllFiles(subDir));
}
}
}
catch
{
}
Comment on lines +154 to +156
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The empty catch { } in GetAllFiles will silently hide IO/permission/path errors and may lead to non-obvious mis-detections (e.g., returning Unknown/missing markers without any diagnosability). Prefer catching specific exceptions (e.g., UnauthorizedAccessException, IOException, PathTooLongException) and either (a) surface a meaningful result (like “inconclusive”) or (b) log at debug/trace level so failures can be investigated without crashing.

Suggested change
catch
{
}
catch (UnauthorizedAccessException ex)
{
System.Diagnostics.Debug.WriteLine($"[ProjectTypeDetector] Access denied while enumerating directory '{directory}': {ex}");
}
catch (IOException ex)
{
System.Diagnostics.Debug.WriteLine($"[ProjectTypeDetector] I/O error while enumerating directory '{directory}': {ex}");
}
catch (PathTooLongException ex)
{
System.Diagnostics.Debug.WriteLine($"[ProjectTypeDetector] Path too long while enumerating directory '{directory}': {ex}");
}

Copilot uses AI. Check for mistakes.

return files;
}

private string? SafeReadFile(string filePath)
{
try
{
return File.ReadAllText(filePath);
}
catch
{
return null;
}
}
}
}
2 changes: 2 additions & 0 deletions BannerlordModEditor.UI/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@

// 注册Common层服务
services.AddTransient<BannerlordModEditor.Common.Services.IFileDiscoveryService, BannerlordModEditor.Common.Services.FileDiscoveryService>();
services.AddSingleton<BannerlordModEditor.Common.Services.IGameDirectoryScanner, BannerlordModEditor.Common.Services.GameDirectoryScanner>();

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Release)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Release)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Release)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Release)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / macos-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / tmux-integration-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / windows-tests (9.0.x)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / unit-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / unit-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / unit-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / unit-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / integration-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / integration-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / integration-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / integration-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / concurrency-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / concurrency-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / concurrency-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / concurrency-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / ui-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / ui-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / ui-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / ui-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / test (Debug)

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / large-xml-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / large-xml-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / large-xml-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / large-xml-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / regression-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / regression-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / regression-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / regression-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / performance-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / performance-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / performance-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / performance-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / memory-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / memory-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / memory-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / memory-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / error-handling-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / error-handling-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / error-handling-tests

The type or namespace name 'GameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)

Check failure on line 74 in BannerlordModEditor.UI/App.axaml.cs

View workflow job for this annotation

GitHub Actions / error-handling-tests

The type or namespace name 'IGameDirectoryScanner' does not exist in the namespace 'BannerlordModEditor.Common.Services' (are you missing an assembly reference?)
services.AddSingleton<BannerlordModEditor.Common.Services.IProjectTypeDetector, BannerlordModEditor.Common.Services.ProjectTypeDetector>();

// 注册所有编辑器ViewModel和View
services.AddTransient<AttributeEditorViewModel>();
Expand Down
Loading