# Registering Classes Instead of Instances

**URL:** https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469
**Category:** dry-system
**Created:** [June 3, 2022, 2:46pm UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469 "2022-06-03T14:46:32Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![ternaryCat](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/ternarycat/32/767_2.png) [@ternaryCat](https://discourse.dry-rb.org/u/ternaryCat)
#### Post date: [June 3, 2022, 2:46pm UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/1 "2022-06-03T14:46:32Z")

</div>

Hi

I’m trying to move my application to dry-system. I regiestred my models by “config.component\_dirs.add” and when i try to call my models, i get instances of these classes, but there are methods in the classes that I use.

Is there clean way to register my models?

---

<div class="post-metadata">

### Author: ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)
#### Post date: [June 3, 2022, 4:48pm UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/2 "2022-06-03T16:48:22Z")

</div>

Yes, this is supported via the [`instance` proc](https://github.com/dry-rb/dry-system/pull/215).

This was mentioned in the [CHANGELOG for 0.23](https://github.com/dry-rb/dry-system/blob/main/CHANGELOG.md#0230-2022-02-08)

```ruby
config.component_dirs.add "app" do |dir|
  dir.instance = proc do |component|
    if component.identifier.include?("entities")
      component.loader.constant(component)
    else
      component.loader(component)
    end
  end
end

```

Another approach you can take is using the [zeitwerk plugin](https://dry-rb.org/gems/dry-system/0.23/plugins/#zeitwerk) so you can reference the constants directly.

---

<div class="post-metadata">

### Author: ![ternaryCat](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/ternarycat/32/767_2.png) [@ternaryCat](https://discourse.dry-rb.org/u/ternaryCat)
#### Post date: [June 3, 2022, 7:58pm UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/3 "2022-06-03T19:58:01Z")

</div>

I tried to implement the loading according to your example, but `dir.instance` never called. I’ve added puts to Proc and didn’t see any output in the console, my models loaded as instances :^( (I use the last version of dry-system)

UPD: Sorry, I didn’t expect that dir.instance calls when I try to get access to my component. It’s working. Thank you :^)

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [June 7, 2022, 8:17am UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/4 "2022-06-07T08:17:19Z")

</div>

I don’t recommend using both class and instance methods. It defeats the purpose of using dry-system with DI as you end up with code coupled to class constants anyway.

---

<div class="post-metadata">

### Author: ![wuarmin](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/wuarmin/32/641_2.png) [@wuarmin](https://discourse.dry-rb.org/u/wuarmin)
#### Post date: [June 8, 2022, 10:59am UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/5 "2022-06-08T10:59:31Z")

</div>

@solnic WDYM with using both class and instance methods? You mean you don’t recommend using zeitwerk? Cause with zeitwerk your code will be coupled to class constants etc. But I do not see an issue with something like this:

```ruby
App["serializers.user"].to_json(user)
# instead of Serialzers::User.to_json(user)

```

---

<div class="post-metadata">

### Author: ![bestwebua](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/bestwebua/32/760_2.png) [@bestwebua](https://discourse.dry-rb.org/u/bestwebua)
#### Post date: [June 8, 2022, 3:11pm UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/6 "2022-06-08T15:11:07Z")

</div>

@ [alassek](https://discourse.dry-rb.org/u/alassek) Thanks, good point!

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [June 9, 2022, 8:39am UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/7 "2022-06-09T08:39:29Z")

</div>

> [@wuarmin](#):
>
> WDYM with using both class and instance methods?

I literally meant what I wrote, relying on both class and instance methods creates coupling between class constants and code that uses them and mixes that with instance methods, which adds more complexity to the way a system is structured. When you use dry-system, it’s recommended to rely on instance methods exclusively, this has proven to be a great architectural pattern that reduces complexity of the code base and makes it more flexible and coherent.

> [@wuarmin](#):
>
> You mean you don’t recommend using zeitwerk? Cause with zeitwerk your code will be coupled to class constants etc

Zeitwerk is an autoloader, what does this have to do with coupling to class constants?

---

<div class="post-metadata">

### Author: ![wuarmin](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/wuarmin/32/641_2.png) [@wuarmin](https://discourse.dry-rb.org/u/wuarmin)
#### Post date: [June 9, 2022, 9:06am UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/8 "2022-06-09T09:06:50Z")

</div>

@solnic Sorry that was a misunderstanding. Reading your answer I thought it was related to alassek’s answer and thought that you don’t recommend registering class constants. Now I realized that you only responded to the initial question.

> Zeitwerk is an autoloader, what does this have to do with coupling to class constants?

Because all class constants are available through Zeitwerk, it’s tempting to bypass the DI. That’s what I meant, but forget it.

thanks and best regards.

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [June 13, 2022, 9:36am UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/9 "2022-06-13T09:36:49Z")

</div>

> [@wuarmin](#):
>
> @solnic Sorry that was a misunderstanding. Reading your answer I thought it was related to alassek’s answer and thought that you don’t recommend registering class constants. Now I realized that you only responded to the initial question.

Ah thanks I see the misunderstanding now too. I don’t recommend registering class constants when they are also used to create instances, because that’s the type of inconsistency that we’re trying to avoid when using dry-system. Relying on instances exclusively works much better.

> [@wuarmin](#):
>
> Because all class constants are available through Zeitwerk, it’s tempting to bypass the DI

Ah gotcha, yes so to clarify - when you use Zeitwerk and refer to class constants explicitly and bypass the DI provided by dry-system **then** you’re going to introduce tight coupling between your code and class constants. When you use Zeitwerk setup via dry-system just to have it auto-load constants (which of course also means having it load files too) **but** you still use DI and don’t refer to class constants explicitly, then there’s no such coupling.

---

<div class="post-metadata">

### Author: ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)
#### Post date: [June 14, 2022, 3:25am UTC](https://discourse.dry-rb.org/t/registering-classes-instead-of-instances/1469/10 "2022-06-14T03:25:13Z")

</div>

@wuarmin This is sound advice and I think you should follow this rule of thumb _in most cases_.

I sometimes reference class constants in my code, but @solnic is correct here that it introduces coupling so take great care when doing this.

I’ll give a couple examples of why I do this. I occasionally write singeton helper methods on module namespaces that aren’t tied to a specific implementation. This is far less dangerous because namespaces change less often than implementations.

Here’s a concrete example: while my application code uses ROM repositories as the primary interface to the data layer, in many cases I need to just open a console and poke around to investigate. This leads to a really common pattern.

```ruby
db = App["persistence.db"]
db[:table_name].where(simple: "query").all

rom = App["persistence.rom"]
rom[:relation_name].where(simple: "query").to_a

```

I organize my data layer in the `DB` namespace, with ROM Relations living in `DB::Relation`. So I wrote a couple simple helper methods.

```ruby
DB[:table_name].where(simple: "query").all
DB::Relation[:relation_name].where(simple: "query").to_a

```

Under the hood, my helper methods are still using the container system so I still have the benefits of swapping implementation if necessary.

This is also useful for simple Rake tasks that don’t merit being implemented as a full-blown class.

Another common reason is pattern-matching, if I just need to know an operation succeeded and returned the type I expect. This is also not a serious case of coupling because I’m not depending on an interface in these cases, just identity. And search-replacing a specific constant name is very easy.
