C
C#•8mo ago
Ploxi

Best Practices for Instantiating Objects in C# Source Generators

I am writing a sourcegen. We need a way of instantiating SomeArgs in SomeService. Currently the sourcegen is just newing up SomeArgs.
[CreateConfigurableTask]
public class SomeArgs
{
public string SomeStuff { get; set; }
public string SomeStuff1 { get; set; }

public SomeArgs WithSomeStuff(string someStuff)
{
SomeStuff = someStuff;
return this;
}

public async Task<SomeArgs> SomeAsyncOperation(string myParam)
{
await Task.Delay(10);
return this;
}
}

public partial class SomeService
{
private Task<string> DoSomething(SomeArgs data)
{
return Task.FromResult($"Doing something with {data.SomeStuff} and {data.SomeStuff1}");
}
}
[CreateConfigurableTask]
public class SomeArgs
{
public string SomeStuff { get; set; }
public string SomeStuff1 { get; set; }

public SomeArgs WithSomeStuff(string someStuff)
{
SomeStuff = someStuff;
return this;
}

public async Task<SomeArgs> SomeAsyncOperation(string myParam)
{
await Task.Delay(10);
return this;
}
}

public partial class SomeService
{
private Task<string> DoSomething(SomeArgs data)
{
return Task.FromResult($"Doing something with {data.SomeStuff} and {data.SomeStuff1}");
}
}
Here are some ideas: - Mark a method with an attribute that generates SomeArgs like that:
[ConfigurableTaskArgsFactory]
public SomeArgs CreateSomeArgs()
{
return new SomeArgs();
}
[ConfigurableTaskArgsFactory]
public SomeArgs CreateSomeArgs()
{
return new SomeArgs();
}
- The sourcegen simply using IServiceProvider to get the instance of SomeArgs behind the scenes. Could be hard to see through what is happening. - Use a delegate in the generated partial class to create SomeArgs like that:
public partial class SomeService
{
private Func<SomeArgs> _createSomeArgs = () => new SomeArgs();
}
public partial class SomeService
{
private Func<SomeArgs> _createSomeArgs = () => new SomeArgs();
}
What are your thoughts on this?
3 Replies
lycian
lycian•8mo ago
I don't follow. Is the sourcegen creating the factory for SomeArgs or is there some method/delegate that is provide for creating SomeArgs that the generated code needs?
Ploxi
PloxiOP•8mo ago
Depends on the option. The delegate sln would create a delegate in the generated source and the user could overwrite the value in the ctor. In the attrib sln, the sourcegen would simply use new() unless a method exists in the user code that is attributed Ok just reread the issue and its really bad described - sry 😅 So basically the sourcegen is generating methods that call the existing ones in the service and needs a way of newing up the args in a way that is kinda interceptable
lycian
lycian•8mo ago
Marking methods as what the generator will use is a bit cleaner and easier to understand, but it probably depends on how many types you have to do that with and if it starts to pollute the codebase You might get more opinions for SG professionals in #roslyn if you wanted more opinions on this
Want results from more Discord servers?
Add your server