Last active
September 13, 2021 06:30
-
-
Save GeeWee/c8dd754fe17ebfd3665c8c3ed220f328 to your computer and use it in GitHub Desktop.
Fun with attributes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Startup | |
{ | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddControllers(); | |
// This uses Scrutor to scan for all classes with a [Transient] [Scoped] or [Singleton] attribute and adds them as any matching interfaces | |
// No need to add any extra logic in Startup.cs when defining classes | |
services.Scan(i => | |
i.FromCallingAssembly() | |
.AddClasses(c => c.WithAttribute<TransientAttribute>()) | |
.AsImplementedInterfaces() | |
.WithTransientLifetime() | |
.AddClasses(c => c.WithAttribute<ScopedAttribute>()) | |
.AsImplementedInterfaces() | |
.WithScopedLifetime() | |
.AddClasses(c => c.WithAttribute<SingletonAttribute>()) | |
.AsImplementedInterfaces() | |
.WithSingletonLifetime() | |
); | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |
{ | |
if (env.IsDevelopment()) | |
{ | |
app.UseDeveloperExceptionPage(); | |
} | |
app.UseRouting(); | |
app.UseEndpoints(endpoints => | |
{ | |
endpoints.MapControllers(); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Note the two attributes [Transient] which ensures that the lifetime is set as transient | |
// but notice also [AutoGenerateInterface]. This attribute means that the ISomeThirdClass interface is generated automatically | |
// with all the public methods of SomeThirdClass specified. No need to write a single line of code if you want the interface | |
// and the class to match 1:1 | |
[Transient] | |
[AutoGenerateInterface] | |
public class SomeThirdClass : ISomeThirdClass | |
{ | |
public string Bar() | |
{ | |
return "SomeThirdClass return value"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Notice here that this is close to the class above, but the lifetime is Singleton, so the "Counter" variable keeps its state. | |
[Singleton] | |
[AutoGenerateInterface] | |
public class SomeOtherClass : ISomeOtherClass | |
{ | |
public int Counter { get; set; } = 0; | |
public string Foo() | |
{ | |
Counter += 1; | |
return $"SomeOtherClass counter value: {Counter}"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Notice that here there's also a "AutoGenerateConstructor" attribute. This Source Generator reads all fields of the class | |
// and automatically generates a constructor based on the fields, that ASP.NET Core can use to inject the dependencies. | |
// You can also use this constructor to instantiate the class in e.g. tests. | |
// Notice that thi class also usees the auto-generated interfaces from the other classes and not the classes directly. | |
[AutoGenerateConstructor] | |
[AutoGenerateInterface] | |
[Transient] | |
public partial class SomeClass : ISomeClass | |
{ | |
private ISomeOtherClass _someClass1; | |
private ISomeThirdClass _someClass2; | |
public string Test() | |
{ | |
return _someClass1.Foo() + "\n" + _someClass2.Bar(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Auto-generating constructors also work in the controller layer! | |
[AutoGenerateConstructor] | |
[ApiController] | |
[Route("/test")] | |
public partial class TestController : ControllerBase | |
{ | |
private ISomeClass _someClass; | |
[HttpGet] | |
public ActionResult<string> Index() | |
{ | |
return _someClass.Test(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment