Skip to content

Commit 603ea68

Browse files
committed
Awareness email.
1 parent 6f69f3b commit 603ea68

File tree

4 files changed

+196
-0
lines changed

4 files changed

+196
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Discover Metalama: A New Code Generation Toolkit for C#
2+
3+
Hi {{firstName}},
4+
5+
My name is **{{sendingAccountFirstName}}** and I’m helping PostSharp’s founder to gather feedback about **Metalama**, a new, free code generation and validation toolkit for C#.
6+
7+
Given your experience in .NET, I thought you might be interested to learn about it and, on our side, we’re eager to hear your opinion, therefore this cold email.
8+
9+
The idea behind Metalama is that you write custom attributes called **aspects**, which work as code templates. Here is our Hello World example: a logging aspect.
10+
11+
```csharp
12+
using Metalama.Framework.Aspects;
13+
14+
public class LogAttribute : OverrideMethodAspect
15+
{
16+
  public override dynamic? OverrideMethod()
17+
  {
18+
    Console.WriteLine( "Entering {meta.Target.Method}." );
19+
    try
20+
    {
21+
       return meta.Proceed();
22+
    }
23+
    finally
24+
    {
25+
       Console.WriteLine( "Leaving {meta.Target.Method}." );
26+
    }
27+
  }
28+
}
29+
```
30+
31+
You can then use the aspect on any method, like this:
32+
33+
```csharp
34+
[Log]
35+
void SomeMethod() => Console.WriteLine( "Hello, World!" );
36+
```
37+
38+
Metalama transforms the code during compilation into this:
39+
40+
```csharp
41+
void SomeMethod()
42+
{
43+
  Console.WriteLine( "Entering Program.SomeMethod()" );
44+
  try
45+
  {
46+
    Console.WriteLine( "Hello, World!" );
47+
  }
48+
  finally
49+
  {
50+
  Console.WriteLine( "Leaving Program.SomeMethod()" );
51+
  }
52+
}
53+
```
54+
55+
It’s possible to preview or even debug the code generated by Metalama. The real benefit of this approach is that you can **drastically reduce repetitive code**. And if you want to change the code generation pattern, you just need to change the aspect. You get the idea!
56+
57+
**Key Benefits of Metalama:**
58+
59+
- **Reduce repetitive code**
60+
- **Easy code modifications**
61+
- **Real-time feedback and code modifications**
62+
- **Preview and debug generated code**
63+
64+
You can find the source code of this example, as well as more examples, on [GitHub](https://github.com/postsharp/Metalama.Demo/blob/master/src/01_Log/LogAttribute.cs?mtm_campaign=awareness&mtm_source=instantly). You can learn more about Metalama thanks to the [video tutorials](https://doc.postsharp.net/metalama/videos?mtm_campaign=awareness&mtm_source=instantly) and [commented examples](https://doc.postsharp.net/metalama/examples?mtm_campaign=awareness&mtm_source=instantly).
65+
66+
Our development team is looking forward to your feedback and questions on our [Slack community workspace](https://www.postsharp.net/slack?mtm_campaign=awareness&mtm_source=instantly). Of course, you can also answer this email and I’ll make sure it will reach an engineer.
67+
68+
Thank you!
69+
70+
All the best,
71+
**{{sendingAccountFirstName}}**
72+
Community Manager
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Validate Naming Conventions with Metalama
2+
3+
Hi {{firstName}},
4+
5+
In my previous email I briefly showed how you can use Metalama to generate code. Today, I would like to introduce Metalama’s second pillar: code verification.
6+
7+
You’ve perhaps experienced how hard it can be to align everyone on the same naming conventions. With Metalama, you define rules and conventions using plain C#. They will be enforced both in real-time in the IDE and at compile time.
8+
9+
For instance, assume you want every class implementing IInvoiceFactory to have the InvoiceFactory suffix. You can do this with a single attribute.
10+
11+
```csharp
12+
[DerivedTypesMustRespectNamingConvention( "*InvoiceFactory" )]
13+
public interface IInvoiceFactory
14+
{
15+
Invoice CreateFromOrder( Order order );
16+
}
17+
```
18+
19+
If someone violates this rule, a warning will immediately be reported:
20+
21+
```
22+
LAMA0903. The type ‘MyInvoiceConverted’ does not respect the naming convention set on the base class or interface ‘IInvoiceFactory’. The type name should match the "\*InvoiceFactory" pattern.
23+
```
24+
25+
The shorter the feedback loop is, the smoother the code reviews will go! Not talking about the frustration both sides avoided!
26+
27+
You can learn more about code validation with Metalama in our [online documentation](https://doc.postsharp.net/metalama/examples?mtm_campaign=awareness&mtm_source=instantly).
28+
29+
As I wrote in my first email, our development team is looking forward to your feedback and questions on our [Slack community workspace](https://www.postsharp.net/slack?mtm_campaign=awareness&mtm_source=instantly). Of course, you can also answer this email and I’ll make sure it will reach an engineer.
30+
31+
Thank you!
32+
33+
All the best,
34+
**{{sendingAccountFirstName}}**
35+
Community Manager
36+
37+
_P.S. We will send you 3 more emails about Metalama and then stop. You can unsubscribe at any time._
38+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Here is How to Save Time on Caching
2+
3+
14
Hello!
25

36
It's Fedja from Metalama again. In my previous emails, I described Metalama as a meta-programming _framework_ that allows you to generate and validate code as you type.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Get your development team to adhere to architecture
2+
3+
Developers need to follow specific rules and conventions to work together effectively as a team. This adherence ensures that individual contributions integrate seamlessly into the overall application.
4+
5+
In a previous email, we discussed how to enforce naming conventions. Today, let's examine how to verify that components are _used_ as expected. You might have just written a method meant only to support a test, but how can you enforce that it's not used in production code?
6+
7+
* Option 1: Add comments such as **DO NOT USE IN PRODUCTION CODE!**, hoping the exclamation mark will help.
8+
* Option 2: Rely on code reviews. This can be slow, frustrating, and costly.
9+
* Option 3: Make your architecture _executable_ so it can be automatically enforced straight from the editor. You guessed it, that's where Metalama comes in handy.
10+
11+
The [open-source](https://github.com/postsharp/Metalama.Extensions/tree/HEAD/src/Metalama.Extensions.Architecture) [Metalama.Extensions.Architecture](https://www.nuget.org/packages/Metalama.Extensions.Architecture) package offers several pre-made custom attributes and compile-time APIs that cover many common conventions teams might want to follow.
12+
13+
## Custom attributes
14+
15+
Let's assume we have a constructor that slightly modifies the object's behavior to make it more testable. We want to ensure that this constructor is used only in tests. Metalama provides the [CanOnlyBeUsedFrom](https://doc.postsharp.net/etalama/api/metalama-extensions-architecture-aspects-canonlybeusedfromattribute) attribute for this purpose.
16+
17+
```c#
18+
using Metalama.Extensions.Architecture.Aspects;
19+
20+
namespace CommonTasks.ValidatingArchitecture
21+
{
22+
public class OrderShipping
23+
{
24+
private bool isTest;
25+
26+
public OrderShipping()
27+
{
28+
}
29+
30+
[CanOnlyBeUsedFrom(Namespaces = new[] {"**.Tests"})]
31+
public OrderShipping(bool isTest)
32+
{
33+
// Used to trigger specific test configuration
34+
this.isTest = isTest;
35+
}
36+
}
37+
}
38+
```
39+
40+
If we attempt to create a new `OrderShipping` instance in a namespace that isn't suffixed by `Tests`, we will see a warning.
41+
42+
![](../metalama-email-course/images/ValidationWarning.jpg)
43+
44+
## Fabrics
45+
46+
Suppose we have a project composed of a large number of components. Each of these components is implemented in its own namespace and is made up of several classes. There are so many components that we don't want to have them each in their own project.
47+
48+
However, we still want to isolate components from each other. Specifically, we want `internal` members of each namespace to be visible only within this namespace. Only `public` members should be accessible outside of its home namespace.
49+
50+
Additionally, we want `internal` components to be accessible from any test namespace.
51+
52+
With Metalama, you can validate each namespace by adding a _fabric_ type: a compile-time class that executes within the compiler or the IDE.
53+
54+
```cs
55+
namespace MyComponent
56+
{
57+
internal class Fabric : NamespaceFabric
58+
{
59+
public override void AmendNamespace(INamespaceAmender amender)
60+
{
61+
amender.InternalsCanOnlyBeUsedFrom(from =>
62+
from.CurrentNamespace().Or(or => or.Type("**.Tests.**")));
63+
}
64+
}
65+
}
66+
```
67+
68+
Now, if some foreign code tries to access an internal API of the `MyComponent` namespace, a warning will be reported.
69+
70+
In addition to `InternalsCanOnlyBeUsedFrom`, the package also includes `InternalsCannotBeUsedFrom`, `CanOnlyBeUsedFrom`, and `CannotOnlyBeUsedFrom`. You can easily build more rules based on the code model.
71+
72+
## Conclusion
73+
74+
We've just seen two examples of how you can validate your code using pre-built Metalama aspects or compile-time APIs.
75+
76+
Enforcing rules and conventions in this manner allows you to:
77+
78+
- Eliminate the need for a written set of rules to which everyone must refer.
79+
- Provide immediate feedback to developers within the familiar confines of the IDE itself.
80+
- Improve code reviews as they now only need to focus on the code itself.
81+
- Simplify the codebase because it adheres to consistent rules.
82+
83+
You can learn more about architecture validation in our online [documentation](https://doc.postsharp.net/metalama/conceptual/architecture/usage).

0 commit comments

Comments
 (0)