<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Acmion</title>
    <description>The latest articles on DEV Community by Acmion (@acmion).</description>
    <link>https://dev.to/acmion</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F471935%2F459a5352-4522-4fcc-8a3f-92377618b0db.png</url>
      <title>DEV Community: Acmion</title>
      <link>https://dev.to/acmion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/acmion"/>
    <language>en</language>
    <item>
      <title>Julia Object Oriented Programming</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Sat, 29 May 2021 19:36:26 +0000</pubDate>
      <link>https://dev.to/acmion/julia-object-oriented-programming-5dgh</link>
      <guid>https://dev.to/acmion/julia-object-oriented-programming-5dgh</guid>
      <description>&lt;p&gt;Julia is a nice and promising scientific language for high performance computing, with the central paradigm of multiple dispatch. However, Julia does only partially support object oriented programming (OOP) with dot notation. For example, "objects" can not have their own methods. Unfortunately, this happens to be the style of programming that I prefer. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/39133424/how-to-create-a-single-dispatch-object-oriented-class-in-julia-that-behaves-l"&gt;This StackOverflow question&lt;/a&gt;&lt;br&gt;
discusses the matter, however, the fields (if exposed) in the solution get wrapped in &lt;code&gt;Core.Box&lt;/code&gt;, which kind of defeats the purpose of fields, as they can no longer be accessed in the manner that one would expect.&lt;/p&gt;

&lt;p&gt;I figured out an undocumented way in which object oriented programming with dot notation, including methods and without boxing, can be implemented and decided to write this post so that the knowledge can be passed on and the relative common question of dot notational OOP in Julia could be answered with more than "No, it does not work". Additionally, I hope that this way of programming would become more widely supported in Julia.&lt;/p&gt;
&lt;h2&gt;
  
  
  Python Vs Julia Classes
&lt;/h2&gt;

&lt;p&gt;Consider the following class in Python and how it's methods are called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Python
class ExampleClass:
    def __init__(self, field_0, field_1):
        self.field_0 = field_0
        self.field_1 = field_1

    def method_0(self):
        return self.field_0 * self.field_1

    def method_1(self, n):
        return (self.field_0 + self.field_1) * n

    def method_2(self, val_0, val_1):
        self.field_0 = val_0
        self.field_1 = val_1

ex = ExampleClass(10, 11)
ex.method_0()
ex.method_1(1)
ex.method_2(20, 22)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The common way to implemented this in Julia would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Julia
mutable struct ExampleClass
    field_0
    field_1
end

function method_0(example_class)
    return example_class.field_0 * example_class.field_1
end

function method_1(example_class, n)
    return (example_class.field_0 + example_class.field_1) * n
end

function method_2(example_class, val_0, val_1)
    example_class.field_0 = val_0
    example_class.field_1 = val_1
end

ex = ExampleClass(10, 11)
method_0(ex)
method_1(ex, 1)
method_2(ex, 20, 22)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key difference between these two examples is that the methods in Python belong to the object and the functions in Julia belong to the global scope. I do not like the concept of global scope and would like to avoid it as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Julia OOP Methods With Dot Notation
&lt;/h2&gt;

&lt;p&gt;By implementing the class in a different way we can replicate the Pythonic dot notation. Consider the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Julia
mutable struct ExampleClass
    field_0
    field_1
    method_0
    method_1
    method_2

    function ExampleClass(field_0, field_1)
        this = new()

        this.field_0 = field_0
        this.field_1 = field_1

        this.method_0 = function()
            return this.field_0 * this.field_1
        end

        this.method_1 = function(n)
            return (this.field_0 + this.field_1) * n
        end

        this.method_2 = function(val_0, val_1)
            this.field_0 = val_0
            this.field_1 = val_1
        end

        return this
    end
end

ex = ExampleClass(10, 11)
ex.method_0()
ex.method_1(1)
ex.method_2(20, 22)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it works like in Python, just as I like it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Private Variables
&lt;/h2&gt;

&lt;p&gt;What about private variables? I see that there are two ways in which private variables can be implemented. One is to add new fields to the&lt;br&gt;
struct, but prefix them with an underscore like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Julia
mutable struct ExampleClass
    field_0
    field_1
    method_0
    method_1
    method_2
    _private_var

    function ExampleClass(field_0, field_1)
        this = new()
        this._private_var = 0
        ...
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, the variables are not really private and can still be accessed from the outside. Another way, with truly private variables &lt;br&gt;
is to include them in the constructor like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Julia
mutable struct ExampleClass
    field_0
    field_1
    method_0
    method_1
    method_2

    function ExampleClass(field_0, field_1)
        this = new()
        private_var = 0

        ...
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the private variables are really private, however, they can not be accessed with dot notation from &lt;code&gt;this&lt;/code&gt;, which is unfortunate. &lt;br&gt;
I prefer the underscore method.&lt;/p&gt;
&lt;h2&gt;
  
  
  How Does it Work?
&lt;/h2&gt;

&lt;p&gt;The revised Julia code relies primarily on three things: closures, variable capturing and anonymous functions. &lt;/p&gt;
&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;p&gt;Unfortunately this way of programming has some caveats, at least when compared to the "idiomatic" Julia way. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The size of the classes grow,  with each method increasing the size by 8 bytes (at least on 64 bit systems) and thus allocation becomes slightly slower. &lt;/li&gt;
&lt;li&gt;Calling the anonymous functions is slightly slower than calling the global functions. &lt;/li&gt;
&lt;li&gt;Capturing variables in Julia has some performance implications. See the &lt;a href="https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured"&gt;Julia docs&lt;/a&gt;.
Using &lt;code&gt;let this = this&lt;/code&gt; may have some performance benefit when applied to the anonymous functions, but I am uncertain of its effects in this case.&lt;/li&gt;
&lt;li&gt;The classes (or structs) must be mutable, since they are modified in the constructor. This can perhaps be circumvented in some fashion.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Performance Evaluation
&lt;/h2&gt;

&lt;p&gt;This section provides a quick performance comparison between the both styles in Julia. Note that the results are highly dependent on the fields and &lt;br&gt;
methods of the classes and as such this test should not be considered to be representative of every situation. This test focuses on allocation &lt;br&gt;
and method call performance. You should benchmark your own code for your self, which probably has other underlying assumptions. The benchmarks are executed &lt;br&gt;
with these two types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Julia
mutable struct DotNotationType
    field_0::Int
    field_1::Int
    field_2::Int
    field_3::Int
    do_work::Function

    function DotNotationType(field_0::Int, field_1::Int, field_2::Int, field_3::Int)
        this = new()
        this.field_0 = field_0
        this.field_1 = field_1        
        this.field_2 = field_3
        this.field_2 = field_3


        this.do_work = function(n::Int)
            sum = 0

            for i in 1:n
                sum += this.field_0 * this.field_1 + this.field_2 * this.field_3 ^ n 
            end

            return sum
        end

        return this
    end
end

mutable struct GlobalScopeType
    field_0::Int
    field_1::Int
    field_2::Int
    field_3::Int
end

function do_work(gst::GlobalScopeType, n::Int)
    sum = 0

    for i in 1:n
        sum += gst.field_0 * gst.field_1 + gst.field_2 * gst.field_3 ^ n 
    end

    return sum
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Boxing &amp;amp; Class Sizes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;println(DotNotationType(1, 2, 3, 4).field_0)
println(DotNotationType(1, 2, 3, 4).method_0)

println(sizeof(DotNotationType))
println(sizeof(GlobalScopeType))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1
#61

40
32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fields of &lt;code&gt;DotNotationType&lt;/code&gt; are not boxed within &lt;code&gt;Core.Box&lt;/code&gt;, as in &lt;a href="https://stackoverflow.com/questions/39133424/how-to-create-a-single-dispatch-object-oriented-class-in-julia-that-behaves-l"&gt;this question on StackOverflow&lt;/a&gt;. &lt;br&gt;
Additionally, the size of &lt;code&gt;DotNotationType&lt;/code&gt; is &lt;strong&gt;8 bytes&lt;/strong&gt;, or &lt;strong&gt;1.25x&lt;/strong&gt;, larger than the size of &lt;code&gt;GlobalScopeType&lt;/code&gt;. Note that in "real" OOP languages, methods on a class do not generally make its memory imprint larger. This is due to the fact that the methods are conceptually placed in the global scope at compile time (not accounting for anonymous functions in other languages).&lt;/p&gt;

&lt;h3&gt;
  
  
  Allocation Performance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Pkg
Pkg.add("BenchmarkTools")
using BenchmarkTools

function allocate_DotNotationType()
    types = DotNotationType[]

    for i in 1:100000
        push!(types, DotNotationType(i, i * i - i))
    end

    return types
end

function allocate_GlobalScopeType()
    types = GlobalScopeType[]

    for i in 1:100000
        push!(types, GlobalScopeType(i, i * i - i))
    end

    return types
end

# Assuming execution from a Jupyter Notebook
display(@benchmark allocate_DotNotationType())
display(@benchmark allocate_GlobalScopeType())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BenchmarkTools.Trial: 
  memory estimate:  78.89 KiB
  allocs estimate:  2010
  --------------
  minimum time:     23.629 μs (0.00% GC)
  median time:      26.958 μs (0.00% GC)
  mean time:        34.836 μs (17.34% GC)
  maximum time:     3.753 ms (96.40% GC)
  --------------
  samples:          10000
  evals/sample:     1
BenchmarkTools.Trial: 
  memory estimate:  63.27 KiB
  allocs estimate:  1010
  --------------
  minimum time:     17.818 μs (0.00% GC)
  median time:      20.827 μs (0.00% GC)
  mean time:        26.720 μs (15.82% GC)
  maximum time:     3.183 ms (95.79% GC)
  --------------
  samples:          10000
  evals/sample:     1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allocating &lt;code&gt;DotNotationType&lt;/code&gt; is about &lt;strong&gt;1.29x&lt;/strong&gt; (comparing medians) slower than allocating &lt;code&gt;GlobalScopeType&lt;/code&gt;. This seems to be directly dependent on the &lt;br&gt;
fact that the size of &lt;code&gt;DotNotationType&lt;/code&gt; is &lt;strong&gt;1.25x&lt;/strong&gt; larger than the size of &lt;code&gt;GlobalScopeType&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method Performance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Pkg
Pkg.add("BenchmarkTools")
using BenchmarkTools
dnts = allocate_DotNotationType()
gsts = allocate_GlobalScopeType()

function call_DotNotationType(dnts)
    sum = 0.0

    for d in dnts
        sum += d.do_work(4)
    end

    return sum
end

function call_GlobalScopeType(gsts)
    sum = 0.0

    for g in gsts
        sum += do_work(g, 4)
    end

    return sum
end

# Assuming execution from a Jupyter Notebook
display(call_DotNotationType(dnts))
display(call_GlobalScopeType(gsts))

display(@benchmark call_DotNotationType(dnts))
display(@benchmark call_GlobalScopeType(gsts))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-6.042282548123895e20
-6.042282548123895e20
BenchmarkTools.Trial: 
  memory estimate:  31.25 KiB
  allocs estimate:  2000
  --------------
  minimum time:     72.623 μs (0.00% GC)
  median time:      74.246 μs (0.00% GC)
  mean time:        79.119 μs (1.95% GC)
  maximum time:     2.326 ms (96.27% GC)
  --------------
  samples:          10000
  evals/sample:     1
BenchmarkTools.Trial: 
  memory estimate:  16 bytes
  allocs estimate:  1
  --------------
  minimum time:     24.066 μs (0.00% GC)
  median time:      31.175 μs (0.00% GC)
  mean time:        30.374 μs (0.00% GC)
  maximum time:     377.014 μs (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both methods get the same result, which implies that both methods do the same work. However, calling the method of &lt;code&gt;DotNotationType&lt;/code&gt; is about &lt;strong&gt;2.38x&lt;/strong&gt; (comparing medians) slower than calling the function of &lt;code&gt;GlobalScopeType&lt;/code&gt;. I am not entirely sure what is causing the slow down, but it may have something to do with the issues mentioned in the &lt;a href="https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured"&gt;Julia docs about the performance of capturing variables&lt;/a&gt; or it may have something to do with the optimization of anonymous functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OOP is possible in Julia.&lt;/li&gt;
&lt;li&gt;OOP with dot notation methods is possible in Julia.&lt;/li&gt;
&lt;li&gt;OOP without boxing of fields is possible.&lt;/li&gt;
&lt;li&gt;OOP with dot notation does have caveats and generally worse performance.&lt;/li&gt;
&lt;li&gt;OOP dot notation methods in Julia are implemented in a generally inferior approach than that of most mainstream programming languages. Note that this is due to the fact that the way of programming presented in this post declares the functions as anonymous functions. This is not how the most common "real" OOP languages implement class methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great, we got a working solution for object oriented programming with dot notational methods! The issues with the dot notational way of programming may or may not affect the general performance of your application, but I expect that this is highly domain specific. For example, in the "Method Performance" section I specifically focused on measuring the performance of method calls. Measuring the performance of actual work within a method may behave drastically different. Regardless, this may at least be a good way of porting dot notational code from, for example, Python to Julia and hopefully this will encourage Julia to implement true classes with true dot notation!&lt;/p&gt;

</description>
      <category>julia</category>
      <category>oop</category>
      <category>dot</category>
      <category>methods</category>
    </item>
    <item>
      <title>CshtmlComponent V4.0.0 - .NET 5 and More</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Sun, 20 Dec 2020 20:39:48 +0000</pubDate>
      <link>https://dev.to/acmion/cshtmlcomponent-v4-0-0-net-5-and-more-4o4e</link>
      <guid>https://dev.to/acmion/cshtmlcomponent-v4-0-0-net-5-and-more-4o4e</guid>
      <description>&lt;p&gt;CshtmlComponent was just updated to V4.0.0, which adds support for .NET 5 and manual component rendering. Check it out here: &lt;a href="https://cshtml-component.acmion.com"&gt;https://cshtml-component.acmion.com&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;CshtmlComponent is a component library for ASP.NET Core and adds many features that contemporary solutions are lacking. The functionality is quite similar to that of PHP's Laravel Blade templates. You may even find it useful for your own projects.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>CshtmlComponent - Scoped CSS</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Sun, 18 Oct 2020 12:14:10 +0000</pubDate>
      <link>https://dev.to/acmion/cshtmlcomponent-scoped-css-1318</link>
      <guid>https://dev.to/acmion/cshtmlcomponent-scoped-css-1318</guid>
      <description>&lt;p&gt;&lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent&lt;/a&gt; is a component library for ASP.NET Core MVC or Razor Pages applications. The library has an extensive feature set and has served myself well. &lt;/p&gt;

&lt;h2&gt;
  
  
  Scoped CSS
&lt;/h2&gt;

&lt;p&gt;Almost all of the major web component libraries or frameworks support scoped CSS. Scoped CSS is a feature that once you get used to it, you never want to go back to writing global CSS. CshtmlComponent does not explicitly take a stance on the issue, but still allows one to write scoped CSS, albeit SCSS (or SASS) has to be used. This blog post describes how this can be achieved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoped CSS with CshtmlComponent
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install and configure CshtmlComponent. See &lt;a href="https://cshtml-component.acmion.com/#usage"&gt;instructions from the official documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://sass-lang.com/install"&gt;SCSS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Create the component "ExampleComponent", in other words, create the files &lt;code&gt;/Components/ExampleComponent.cshtml&lt;/code&gt; and &lt;code&gt;/Components/ExampleComponent.cshtml.cs&lt;/code&gt;. The files paths are relative to the ASP.NET Core application root path. See more instructions in the documentation.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;/Components/ExampleComponent.cshtml&lt;/code&gt; create markup that resembles this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="example-component"&amp;gt;
    &amp;lt;div class="example-component-content"&amp;gt;
        &amp;lt;!-- Content here. --&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="example-component-slot-content"&amp;gt;
        &amp;lt;!-- Content here. --&amp;gt;

        &amp;lt;!-- NOTE: Important class="child-content". --&amp;gt;
        &amp;lt;div class="child-content"&amp;gt;
            &amp;lt;!-- Render the slot content here. See documentation. --&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- NOTE: Important class="child-content". --&amp;gt;
    &amp;lt;div class="example-component-child-content child-content"&amp;gt;
        &amp;lt;!-- Render the child content here. See documentation. --&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create the file &lt;code&gt;/Components/ExampleComponent.cshtml.scss&lt;/code&gt; with content that resembles this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.example-component
{
    // Style the wrapper here.
    padding: 10px;
    background: rgba(255, 0, 0, 0.1);

    &amp;amp; &amp;gt; .example-component-slot-content
    {
        // Apply styles to the slot content container here.
        padding: 6px;
        border: 4px solid rgba(0, 0, 0, 0.4);
    }

    &amp;amp; &amp;gt; *:not(.child-content)
    {
        // Apply styles to child tags that are used by the component (but not nested under .child-content) here.
        // Note: Requires a wrapper element. In this component, the elements with class="example-component-content" and class="example-component-slot-content" are the wrapper elements. Styles are only applied to children of the wrapper elements.
        h2
        {
            color: red;
        }

        .date
        {
            font-style: italic;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The SCSS under &lt;code&gt;&amp;amp; &amp;gt; *:not(.child-content)&lt;/code&gt; is now scoped!&lt;/li&gt;
&lt;li&gt;Add this to code to &lt;code&gt;ExampleComponent.cshtml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;CshtmlHead&amp;gt;
    &amp;lt;link rel="stylesheet" href="~/dist/Components/ExampleComponent.cshtml.css" /&amp;gt;
&amp;lt;/CshtmlHead&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run SCSS from the commandline with this command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sass --watch Components:wwwroot/dist/Components --style compressed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enjoy scoped CSS in CshtmlComponent!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;The SCSS based scoped CSS in CshtmlComponent is not a 100% substitution for how the scoped CSS works in other frameworks. For example, the class names do not get mangled. &lt;/p&gt;

&lt;p&gt;Additionally, this SCSS based scoping demands that wrapper tags are added to the components. In other words, if a tag was added directly under the main class (in this case "example-component"), then styling under &lt;code&gt;&amp;amp; &amp;gt; *:not(.child-content)&lt;/code&gt; would not be applied to it. &lt;/p&gt;

&lt;p&gt;Regardless, scoped CSS is possible in CshtmlComponent and works just fine. &lt;/p&gt;

&lt;p&gt;See this &lt;a href="https://github.com/Acmion/CshtmlComponentScopedCss"&gt;GitHub repository&lt;/a&gt; for an example on scoped CSS in CshtmlComponent.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CshtmlComponent V3.0.0 - Head and Body Content Injection</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Sun, 11 Oct 2020 05:46:04 +0000</pubDate>
      <link>https://dev.to/acmion/cshtmlcomponent-v3-0-0-head-and-body-content-injection-4n30</link>
      <guid>https://dev.to/acmion/cshtmlcomponent-v3-0-0-head-and-body-content-injection-4n30</guid>
      <description>&lt;p&gt;&lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent&lt;/a&gt; is a component framework for ASP.NET Core Razor Pages and MVC projects. The feature set is extensive and a significant improvement over alternatives. Not for Blazor.&lt;/p&gt;

&lt;h1&gt;
  
  
  V3.0.0
&lt;/h1&gt;

&lt;p&gt;The main feature of V3.0.0 is that you can now directly inject content in both the &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt; elements once per component. This is especially useful in cases where components require extra functionality provided by CSS or JS files. &lt;/p&gt;

&lt;p&gt;The developer may choose whether to prepend or append content to either tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Previous Method
&lt;/h2&gt;

&lt;p&gt;Referencing CSS or JS files was previously also possible, via the usage of &lt;code&gt;CshtmlInitial&lt;/code&gt;, which renders some content once per page. The definitions of components that rely on this could have looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@* Reference the associated component as model. *@
@using SampleRazorPagesApplication
@model ExampleComponent

&amp;lt;CshtmlInitial&amp;gt;
    &amp;lt;link rel="stylesheet" href="/style.css" /&amp;gt;
&amp;lt;/CshtmlInitial&amp;gt;

&amp;lt;!-- The content of the component. --&amp;gt;
&amp;lt;div class="example-component"&amp;gt;
    &amp;lt;h1&amp;gt;
        ExampleComponent: @Model.Title
    &amp;lt;/h1&amp;gt;

    &amp;lt;div class="example-component-child-content"&amp;gt;
        &amp;lt;!-- Render the child content. --&amp;gt;
        @Html.Raw(Model.ChildContent)
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;However, while &lt;code&gt;CshtmlInitial&lt;/code&gt; gets the job done (the content of the tag is only rendered once per page), the problem with this approach is that &lt;code&gt;CshtmlInitial&lt;/code&gt; will render the content wherever the component is first instantiated. &lt;/p&gt;

&lt;h2&gt;
  
  
  New Method
&lt;/h2&gt;

&lt;p&gt;With V3.0.0 we can instead utilize &lt;code&gt;CshtmlHead&lt;/code&gt; or &lt;code&gt;CshtmlBody&lt;/code&gt;, which both render their respective contents once per page (unless otherwise configured). The component definition would now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@* Reference the associated component as model. *@
@using SampleRazorPagesApplication
@model ExampleComponent

&amp;lt;CshtmlHead&amp;gt;
    &amp;lt;link rel="stylesheet" href="/style.css" /&amp;gt;
&amp;lt;/CshtmlHead&amp;gt;

&amp;lt;!-- The content of the component. --&amp;gt;
&amp;lt;div class="example-component"&amp;gt;
    &amp;lt;h1&amp;gt;
        ExampleComponent: @Model.Title
    &amp;lt;/h1&amp;gt;

    &amp;lt;div class="example-component-child-content"&amp;gt;
        &amp;lt;!-- Render the child content. --&amp;gt;
        @Html.Raw(Model.ChildContent)
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now the content within &lt;code&gt;CshtmlHead&lt;/code&gt; would be injected in to the &lt;code&gt;head&lt;/code&gt; element and the DOM would remain clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Benefits of the New Method
&lt;/h2&gt;

&lt;p&gt;The new method brings additional benefits as well. For example, one may configure the ordering and render the content more than once if appropriate. The configurations are relatively complex, please view them at the &lt;a href="https://cshtml-component.acmion.com"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of CshtmlInitial
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CshtmlInitial&lt;/code&gt; has not and will not be deprecated (at least in the near future). It was even improved in this update! Previously, an extra &lt;code&gt;Context&lt;/code&gt; attribute had to be specified. This attribute has now been removed, without affecting behavior, and has resulted in cleaner code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Statement
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://cshtml-component.acmion.com"&gt;documentation of CshtmlComponent&lt;/a&gt; was also revised to account for these new changes. Hopefully the documentation covers both old and new features better than before.&lt;/p&gt;

&lt;p&gt;View the &lt;a href="https://github.com/Acmion/CshtmlComponent"&gt;GitHub repository of CshtmlComponent here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy hacking with CshtmlComponent!&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CshtmlComponent - Typed Slots</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Fri, 02 Oct 2020 20:40:41 +0000</pubDate>
      <link>https://dev.to/acmion/cshtmlcomponent-typed-slots-41n2</link>
      <guid>https://dev.to/acmion/cshtmlcomponent-typed-slots-41n2</guid>
      <description>&lt;p&gt;&lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent&lt;/a&gt; is a component framework, with an extensive feature set, for ASP.NET Core MVC and Razor Pages projects (not for Blazor). &lt;a href="https://github.com/Acmion/CshtmlComponent"&gt;See the GitHub repository of CshtmlComponent here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  CshtmlComponent Named Slots
&lt;/h2&gt;

&lt;p&gt;CshtmlComponent already supports the usage of named slots, but what about typed slots? This post will show how this can be achieved. This is not an extensive tutorial, so you should already be somewhat familiar with CshtmlComponent.&lt;/p&gt;

&lt;p&gt;The Razor markup for a CshtmlComponent that supports named slots could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@using SampleRazorPagesApplication
@model ExampleComponent

&amp;lt;div class="example-component"&amp;gt;
    &amp;lt;h1&amp;gt;
        @Model.Title
    &amp;lt;/h1&amp;gt;

    &amp;lt;div class="example-component-action-bar"&amp;gt;
        @Html.Raw(Model.NamedSlots["ActionBar"])
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="example-component-child-content"&amp;gt;
        @Html.Raw(Model.ChildContent)
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Initialization of a CshtmlComponent with Named Slots
&lt;/h2&gt;

&lt;p&gt;The component could then be initialized with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ExampleComponent Title="Hello World"&amp;gt;
    Some HTML that gets captured in Model.ChildContent.

    &amp;lt;CshtmlSlot Name="ActionBar"&amp;gt;
        Some HTML that gets captured in Model.NamedSlots["ActionBar"].
    &amp;lt;/CshtmlSlot&amp;gt;
&amp;lt;/ExampleComponent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that the slot name must be explicitly stated. This works, but is somewhat annoying and error prone. Luckily, fixing this is quite easy with typed slots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typed Slot Definition
&lt;/h2&gt;

&lt;p&gt;To define a typed slot one should create a class that inherits &lt;code&gt;CshtmlComponentSlot&lt;/code&gt; and set the &lt;code&gt;Name&lt;/code&gt; property in the constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HtmlTargetElement("ExampleComponentActionBar"]
    public class ExampleComponentActionBar: CshtmlComponentSlot
    {
        public ExampleComponentActionBar(IHtmlHelper htmlHelper) : base(htmlHelper)
        {
            Name = "ActionBar";
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's it. You may wish to, for example, store the value for &lt;code&gt;Name&lt;/code&gt; as a static field for better maintainability, but this is not necessary. &lt;/p&gt;

&lt;h2&gt;
  
  
  Initialization of a CshtmlComponent with Typed Slots
&lt;/h2&gt;

&lt;p&gt;With the typed slot definition, the example component can now be initialized like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ExampleComponent Title="Hello World"&amp;gt;
    Some HTML that gets captured in Model.ChildContent.

    &amp;lt;ExampleComponentActionBar&amp;gt;
        Some HTML that gets captured in Model.NamedSlots["ActionBar"].
    &amp;lt;/ExampleComponentActionBar&amp;gt;
&amp;lt;/ExampleComponent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that the name no longer has to be explicitly specified. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;CshtmlComponent supports both named and typed slots. Typed slots bring many advantages, such as making maintenance and refactoring significantly easier. This feature is not yet documented in the actual CshtmlComponent documentation, but will be in the future. &lt;/p&gt;

&lt;p&gt;Please try out &lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent&lt;/a&gt;! You just might find it useful for MVC and Razor Pages projects!&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>csharp</category>
      <category>webdev</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>CshtmlComponent V2.2.0 - Reference Capturing</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Sat, 26 Sep 2020 18:43:27 +0000</pubDate>
      <link>https://dev.to/acmion/cshtmlcomponent-v2-2-0-reference-capturing-4k26</link>
      <guid>https://dev.to/acmion/cshtmlcomponent-v2-2-0-reference-capturing-4k26</guid>
      <description>&lt;p&gt;&lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent&lt;/a&gt; is a component library for ASP.NET Core with an advanced feature set. These features significantly improve developer productivity in MVC or Razor Pages projects. Check out the &lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent documentation&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;Previously with CshtmlComponent, you could write Razor code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ExampleComponent Title="Some title" font-size="1.2rem" background-color="rgba(0, 0, 255, 0.1)"&amp;gt;
    &amp;lt;div&amp;gt;
        Some custom HTML content.
        &amp;lt;Box&amp;gt;
            Supports nested components.
        &amp;lt;/Box&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;CshtmlSlot Name="SlotName0"&amp;gt;
        Some custom HTML content within a named slot. The parent component decides where
        this content is placed.
    &amp;lt;/CshtmlSlot&amp;gt;
    &amp;lt;CshtmlSlot Name="SlotName1"&amp;gt;
        Additional custom HTML content within a second named slot.
        &amp;lt;Box&amp;gt;
            Supports nested components.
        &amp;lt;/Box&amp;gt;
    &amp;lt;/CshtmlSlot&amp;gt;
&amp;lt;/ExampleComponent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The component themselves can always access their own properties, but what if you want to access the properties outside the component's own context? For example, one might need to get a generated ID value to use it in some JS code. This is now possible with CshtmlComponent V2.2.0, where you now can capture the component reference like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ExampleComponent Title="Some title" font-size="1.2rem" background-color="rgba(0, 0, 255, 0.1)"&amp;gt;
    &amp;lt;div&amp;gt;
        Some custom HTML content.

        @{ 
            // Assign a variable to component reference. 
            // The Box component inherits CshtmlComponentReferenceableBase&amp;lt;Box&amp;gt; (a class that inherits CshtmlComponentBase), 
            // which implements this logic. Useful if component properties have to be used outside the component's own context.

            // This is not the default behavior due to the mandatory, but slightly confusing syntax: 
            // public Box : CshtmlComponentReferenceableBase&amp;lt;Box&amp;gt; ....

            var boxReference = new CshtmlComponentReference&amp;lt;Box&amp;gt;();
        }
        &amp;lt;Box Reference="boxReference"&amp;gt;
            Supports nested components.
        &amp;lt;/Box&amp;gt;

        The fontsize of the referenced box is: @boxReference.Component.FontSize
    &amp;lt;/div&amp;gt;
    &amp;lt;CshtmlSlot Name="SlotName0"&amp;gt;
        Some custom HTML content within a named slot. The parent component decides where
        this content is placed.
    &amp;lt;/CshtmlSlot&amp;gt;
    &amp;lt;CshtmlSlot Name="SlotName1"&amp;gt;
        Additional custom HTML content within a second named slot.
        &amp;lt;Box&amp;gt;
            Supports nested components.
        &amp;lt;/Box&amp;gt;
    &amp;lt;/CshtmlSlot&amp;gt;
&amp;lt;/ExampleComponent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;CshtmlComponent documentation: &lt;a href="https://cshtml-component.acmion.com"&gt;https://cshtml-component.acmion.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CshtmlComponent GitHub: &lt;a href="https://github.com/Acmion/CshtmlComponent"&gt;https://github.com/Acmion/CshtmlComponent&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CshtmlComponent Nuget: &lt;a href="https://www.nuget.org/packages/Acmion.CshtmlComponent/"&gt;https://www.nuget.org/packages/Acmion.CshtmlComponent/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webdev</category>
      <category>dotnet</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>CshtmlComponent — A Real ASP.NET Core MVC and Razor Pages Component</title>
      <dc:creator>Acmion</dc:creator>
      <pubDate>Sat, 19 Sep 2020 17:47:26 +0000</pubDate>
      <link>https://dev.to/acmion/cshtmlcomponent-a-real-asp-net-core-mvc-and-razor-pages-component-np2</link>
      <guid>https://dev.to/acmion/cshtmlcomponent-a-real-asp-net-core-mvc-and-razor-pages-component-np2</guid>
      <description>&lt;h1&gt;
  
  
  CshtmlComponent — A Real ASP.NET Core MVC and Razor Pages Component
&lt;/h1&gt;

&lt;p&gt;Have you ever tried working with components in ASP.NET Core MVC or Razor Pages projects? This is a major pain in the ass. The solutions available by default are Tag Helpers, View Components and Razor Components. However, none of these are as customizable and convenient as the components in JavaScript frameworks (Svelte, Vue, etc.). CshtmlComponent aims to fix this.&lt;/p&gt;

&lt;p&gt;CshtmlComponent is developed by &lt;a href="https://acmion.com"&gt;Acmion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CshtmlComponent supports the following:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Razor syntax&lt;/li&gt;
&lt;li&gt;Nested child content&lt;/li&gt;
&lt;li&gt;Runtime compilation&lt;/li&gt;
&lt;li&gt;MVC &amp;amp; Razor Pages&lt;/li&gt;
&lt;li&gt;Lenient file structure&lt;/li&gt;
&lt;li&gt;Named slots&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tag Helpers support the following:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nested child content&lt;/li&gt;
&lt;li&gt;MVC &amp;amp; Razor Pages&lt;/li&gt;
&lt;li&gt;Lenient file structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  View Components support the following:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Razor syntax&lt;/li&gt;
&lt;li&gt;Runtime compilation&lt;/li&gt;
&lt;li&gt;MVC &amp;amp; Razor Pages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Razor Components support the following:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Razor syntax&lt;/li&gt;
&lt;li&gt;Nested child content&lt;/li&gt;
&lt;li&gt;Named slots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: While Razor Components can be used in standard MVC &amp;amp; Razor Pages projects without Blazor, the development experience is quite lacking.&lt;/p&gt;

&lt;h2&gt;
  
  
  CshtmlComponent Features
&lt;/h2&gt;

&lt;p&gt;The feature set of CshtmlComponent is more complete than that of the alternatives, which has resulted in clear improvement in my development speed of ASP.NET Core projects. Hopefully, you will also find it useful!&lt;/p&gt;

&lt;p&gt;Please check out the documentation and the GitHub repository!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cshtml-component.acmion.com"&gt;CshtmlComponent Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Acmion/CshtmlComponent"&gt;CshtmlComponent GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>aspnetcore</category>
      <category>dotnet</category>
      <category>cshtml</category>
    </item>
  </channel>
</rss>
