{"record":{"id":"7ac1594dbbb8c67d","repo":"dotnet/BenchmarkDotNet","slug":"custom-factory-must-have-a-public-parameterless-co","errorCode":null,"errorMessage":"Custom factory must have a public parameterless constructor","messagePattern":"Custom factory must have a public parameterless constructor","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet/Code/CodeGenerator.cs","lineNumber":244,"sourceCode":"\n        private global::BenchmarkDotNet.Autogenerated.Runnable_$ID$.FieldsContainer __fieldsContainer;\n        \n         */\n\n        private static string GetInitializeArgumentFields(BenchmarkCase benchmarkCase)\n            => string.Join(\n                Environment.NewLine,\n                benchmarkCase.Descriptor.WorkloadMethod.GetParameters()\n                    .Select((parameter, index) => $\"this.__fieldsContainer.argField{index} = {benchmarkCase.Parameters.GetArgument(parameter.Name!).ToSourceCode()};\")); // we init the fields in ctor to provoke all possible allocations and overhead of other type\n\n        private static string GetEngineFactoryTypeName(BenchmarkCase benchmarkCase)\n        {\n            var factory = benchmarkCase.Job.ResolveValue(InfrastructureMode.EngineFactoryCharacteristic, InfrastructureResolver.Instance)!;\n            var factoryType = factory.GetType();\n\n            if (!factoryType.GetTypeInfo().DeclaredConstructors.Any(ctor => ctor.IsPublic && !ctor.GetParameters().Any()))\n            {\n                throw new NotSupportedException(\"Custom factory must have a public parameterless constructor\");\n            }\n\n            return factoryType.GetCorrectCSharpTypeName();\n        }\n\n        private static string GetInProcessDiagnoserRouters(BenchmarkBuildInfo buildInfo)\n        {\n            var compositeInProcessDiagnoser = buildInfo.CompositeInProcessDiagnoser;\n            var handlerData = compositeInProcessDiagnoser.GetHandlerData(buildInfo.BenchmarkCase);\n            var sourceCodes = compositeInProcessDiagnoser.InProcessDiagnosers\n                .Select((diagnoser, index) => ToSourceCode(diagnoser, handlerData[index], buildInfo.BenchmarkCase, index))\n                .WhereNotNull();\n            return string.Join($\",\\n\", sourceCodes);\n\n            static string? ToSourceCode(IInProcessDiagnoser diagnoser, InProcessDiagnoserHandlerData handlerData, BenchmarkCase benchmarkCase, int index)\n            {\n                if (handlerData.HandlerType is null)\n                {","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet/Code/CodeGenerator.cs#L226-L262","documentation":"GetEngineFactoryTypeName emits, into the generated harness, the concrete type name of the configured IEngineFactory so the harness can `new` it up via reflection-free source. For that the factory type must expose a public parameterless constructor. If the resolved InfrastructureMode.EngineFactoryCharacteristic points at a type whose only constructors take parameters (or are non-public), NotSupportedException is thrown.","triggerScenarios":"Configuring a custom IEngineFactory implementation that has no public parameterless ctor, e.g. `class MyFactory : IEngineFactory { public MyFactory(SomeDep d){} }`, via .WithEngineFactory(...) or a custom job.","commonSituations":"Writing a custom in-process or hosting engine factory with dependency-injection constructors, or a factory that stores configuration in fields set via ctor params.","solutions":["Add a public parameterless constructor to the custom factory type.","Move configuration out of ctor parameters into settable properties or static/config read inside the factory.","If you need runtime data, read it from the IEngine reference the factory receives at Run/create time rather than the ctor.","Verify with factoryType.GetConstructors() that a public parameterless ctor exists before configuring it."],"exampleFix":"// before\nclass MyFactory : IEngineFactory\n{\n    public MyFactory(EngineOptions opts) { }\n    public IEngine Create() => ...;\n}\n\n// after\nclass MyFactory : IEngineFactory\n{\n    public MyFactory() { }\n    public IEngine Create() => /* read options from a static/config source */ ...;\n}","handlingStrategy":"validation","validationCode":"var factoryType = factory.GetType();\nbool ok = factoryType.GetTypeInfo().DeclaredConstructors\n    .Any(c => c.IsPublic && !c.GetParameters().Any());\nif (!ok)\n    throw new InvalidOperationException($\"{factoryType} needs a public parameterless ctor.\");\nconfig.WithEngineFactory(factory);","typeGuard":"static bool HasPublicParameterlessCtor<T>() where T : IEngineFactory\n    => typeof(T).GetTypeInfo().DeclaredConstructors.Any(c => c.IsPublic && !c.GetParameters().Any());","tryCatchPattern":"try { /* run benchmark with custom factory */ }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"parameterless constructor\"))\n{\n    // add a public parameterless ctor to the factory type and rebuild\n}","preventionTips":["Always give custom IEngineFactory implementations a public parameterless constructor.","Do not rely on constructor DI for factories; read options at Create/Run time.","Verify ctor presence with a reflection check in tests before configuring the factory."],"tags":["engine-factory","code-generation","reflection","constructor","notsupported"],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}