diff --git a/lean/components/docker/lean_runner.py b/lean/components/docker/lean_runner.py
index 4c2260ff..3d704b17 100644
--- a/lean/components/docker/lean_runner.py
+++ b/lean/components/docker/lean_runner.py
@@ -585,13 +585,14 @@ def set_up_csharp_options(self, project_dir: Path, run_options: Dict[str, Any],
"mode": "rw"
}
+ framework_ver = self._docker_manager.get_image_label(image, 'target_framework',
+ DEFAULT_LEAN_DOTNET_FRAMEWORK)
+
# Ensure all .csproj files refer to the version of LEAN in the Docker container
csproj_temp_dir = self._temp_manager.create_temporary_directory()
for path in compile_root.rglob("*.csproj"):
- self._ensure_csproj_uses_correct_lean(compile_root, path, csproj_temp_dir, run_options)
+ self._ensure_csproj_is_valid(compile_root, path, csproj_temp_dir, run_options, framework_ver)
- framework_ver = self._docker_manager.get_image_label(image, 'target_framework',
- DEFAULT_LEAN_DOTNET_FRAMEWORK)
# Set up the MSBuild properties
msbuild_properties = {
"Configuration": "Release" if release else "Debug",
@@ -601,8 +602,6 @@ def set_up_csharp_options(self, project_dir: Path, run_options: Dict[str, Any],
"GenerateAssemblyInfo": "false",
"GenerateTargetFrameworkAttribute": "false",
"AppendTargetFrameworkToOutputPath": "false",
- "AutoGenerateBindingRedirects": "true",
- "GenerateBindingRedirectsOutputType": "true",
"AutomaticallyUseReferenceAssemblyPackages": "false",
"CopyLocalLockFileAssemblies": "true",
"PathMap": f"/LeanCLI={str(compile_root)}",
@@ -770,11 +769,12 @@ def _get_csharp_compile_root(self, project_dir: Path) -> Path:
return project_dir
- def _ensure_csproj_uses_correct_lean(self,
- compile_root: Path,
- csproj_path: Path,
- temp_dir: Path,
- run_options: Dict[str, Any]) -> None:
+ def _ensure_csproj_is_valid(self,
+ compile_root: Path,
+ csproj_path: Path,
+ temp_dir: Path,
+ run_options: Dict[str, Any],
+ net_framework: str) -> None:
"""Ensures a C# project is compiled using the version of LEAN in the Docker container.
When a .csproj file refers to the NuGet version of LEAN,
@@ -791,6 +791,18 @@ def _ensure_csproj_uses_correct_lean(self,
csproj = self._xml_manager.parse(csproj_path.read_text(encoding="utf-8"))
include_added = False
+ if net_framework:
+ target_framework_iter = csproj.iter("TargetFramework")
+ if target_framework_iter:
+ target_frameworks = [framework.text for framework in target_framework_iter]
+ if target_frameworks:
+ if net_framework not in target_frameworks:
+ raise RuntimeError(f"This project is targeting {target_frameworks[0].replace('net', 'Net ')}"
+ f" and {net_framework.replace('net', 'Net ')} is required. Please"
+ f" update the \"Target Framework\" project setting in VSCode to"
+ f" the new SDK or modify the csproj file directly to "
+ f"\"{net_framework}\".")
+
for package_reference in csproj.iter("PackageReference"):
if not package_reference.get("Include", "").lower().startswith("quantconnect."):
continue
diff --git a/lean/constants.py b/lean/constants.py
index 3e24b66f..fdb553e7 100644
--- a/lean/constants.py
+++ b/lean/constants.py
@@ -23,8 +23,8 @@
# we get these values from the image labels, but we still have defaults just in case
DEFAULT_LEAN_PYTHON_VERSION = "3.11"
-DEFAULT_LEAN_STRICT_PYTHON_VERSION = f"{DEFAULT_LEAN_PYTHON_VERSION}.7"
-DEFAULT_LEAN_DOTNET_FRAMEWORK = "net6.0"
+DEFAULT_LEAN_STRICT_PYTHON_VERSION = f"{DEFAULT_LEAN_PYTHON_VERSION}.11"
+DEFAULT_LEAN_DOTNET_FRAMEWORK = "net9.0"
# Label name used in Docker containers to specify the version of Lean being used
CONTAINER_LABEL_LEAN_VERSION_NAME = "lean_version"
diff --git a/tests/commands/test_backtest.py b/tests/commands/test_backtest.py
index 80d48260..3752adf8 100644
--- a/tests/commands/test_backtest.py
+++ b/tests/commands/test_backtest.py
@@ -573,7 +573,7 @@ def test_backtest_auto_updates_outdated_csharp_csproj() -> None:
Debug
AnyCPU
- net6.0
+ net9.0
bin/$(Configuration)
false
CS0618
diff --git a/tests/components/config/test_project_config_manager.py b/tests/components/config/test_project_config_manager.py
index 9bfe80b9..48bd26ec 100644
--- a/tests/components/config/test_project_config_manager.py
+++ b/tests/components/config/test_project_config_manager.py
@@ -60,7 +60,7 @@ def test_get_csharp_libraries_returns_all_libraries_in_package_reference_tags_in
Debug
AnyCPU
- net6.0
+ net9.0
bin/$(Configuration)
false
CS0618
@@ -99,7 +99,7 @@ def test_get_csharp_libraries_skips_invalid_package_reference_tags() -> None:
Debug
AnyCPU
- net6.0
+ net9.0
bin/$(Configuration)
false
CS0618
diff --git a/tests/components/docker/test_lean_runner.py b/tests/components/docker/test_lean_runner.py
index ff2e7138..de5ba8fd 100644
--- a/tests/components/docker/test_lean_runner.py
+++ b/tests/components/docker/test_lean_runner.py
@@ -27,7 +27,7 @@
from lean.components.util.project_manager import ProjectManager
from lean.components.util.temp_manager import TempManager
from lean.components.util.xml_manager import XMLManager
-from lean.constants import DEFAULT_ENGINE_IMAGE, LEAN_ROOT_PATH, DEFAULT_DATA_DIRECTORY_NAME
+from lean.constants import DEFAULT_ENGINE_IMAGE, LEAN_ROOT_PATH, DEFAULT_DATA_DIRECTORY_NAME, DEFAULT_LEAN_DOTNET_FRAMEWORK
from lean.models.utils import DebuggingMethod
from lean.models.docker import DockerImage
from lean.models.modules import NuGetPackage
@@ -97,6 +97,7 @@ def test_run_lean_compiles_csharp_project_in_correct_configuration(release: bool
docker_manager = mock.Mock()
docker_manager.run_image.return_value = True
+ docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK
lean_runner = create_lean_runner(docker_manager)
@@ -123,6 +124,7 @@ def test_run_lean_runs_lean_container_detached() -> None:
docker_manager = mock.Mock()
docker_manager.run_image.return_value = True
+ docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK
lean_runner = create_lean_runner(docker_manager)
@@ -384,6 +386,7 @@ def test_run_lean_sets_image_name_when_debugging_with_vsdbg() -> None:
docker_manager = mock.Mock()
docker_manager.run_image.return_value = True
+ docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK
lean_runner = create_lean_runner(docker_manager)
@@ -407,6 +410,7 @@ def test_run_lean_exposes_ssh_when_debugging_with_rider() -> None:
docker_manager = mock.Mock()
docker_manager.run_image.return_value = True
+ docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK
lean_runner = create_lean_runner(docker_manager)
@@ -556,6 +560,7 @@ def test_run_lean_compiles_csharp_project_that_is_part_of_a_solution(in_solution
docker_manager = mock.Mock()
docker_manager.run_image.return_value = True
+ docker_manager.get_image_label.return_value = DEFAULT_LEAN_DOTNET_FRAMEWORK
root_dir = Path.cwd()
lean_runner = create_lean_runner(docker_manager)