Note that there are some explanatory texts on larger screens.

plurals
  1. POIs interception worth the overhead it creates?
    primarykey
    data
    text
    <p>I'm in the middle of a significant effort to introduce NHibernate into our code base. I figured I would have to use some kind of a DI container, so I can inject dependencies into the entities I load from the database. I chose Unity as that container.</p> <p>I'm considering using Unity's interception mechanism to add a transaction aspect to my code, so I can do e.g. the following:</p> <pre><code>class SomeService { [Transaction] public void DoSomething(CustomerId id) { Customer c = CustomerRepository.LoadCustomer(id); c.DoSomething(); } } </code></pre> <p>and the <code>[Transaction]</code> handler will take care of creating a session and a transaction, committing the transaction (or rolling back on exception), etc.</p> <p>I'm concerned that using this kind of interception will bind me to using Unity pretty much everywhere in the code. If I introduce aspects in this manner, then I must never, ever call <code>new SomeService()</code>, or I will get a service that doesn't have transactions. While this is acceptable in production code, it seems too much overhead in tests. For example, I would have to convert this:</p> <pre><code>void TestMethod() { MockDependency dependency = new MockDependency(); dependency.SetupForTest(); var service = SomeService(dependency); service.DoSomething(); } </code></pre> <p>into this:</p> <pre><code>void TestMethod() { unityContainer.RegisterType&lt;MockDependency&gt;(); unityContainer.RegisterType&lt;IDependency, MockDependency&gt;(); MockDependency dependency = unityContainer.Resolve&lt;MockDependency&gt;(); dependency.SetupForTest(); var service = unityContainer.Resolve&lt;SomeService&gt;(); service.DoSomething(); } </code></pre> <p>This adds 2 lines for each mock object that I'm using, which leads to quite a bit of code (our tests use a lot of stateful mocks, so it is not uncommon for a test class to have 5-8 mock objects, and sometimes more.)</p> <p>I don't think standalone injection would help here: I have to set up injection for every class that I use in the tests, because it's possible for aspects to be added to a class after the test is written.</p> <p>Now, if I drop the use of interception I'll end up with:</p> <pre><code>class SomeService { public void DoSomething(CustomerId id) { Transaction.Run( () =&gt; { Customer c = CustomerRepository.LoadCustomer(id); c.DoSomething(); }); } } </code></pre> <p>which is admittedly not as nice, but doesn't seem that bad either.</p> <p>I can even set up my own poor man's interception:</p> <pre><code>class SomeService { [Transaction] public void DoSomething(CustomerId id) { Interceptor.Intercept( MethodInfo.GetCurrentMethod(), () =&gt; { Customer c = CustomerRepository.LoadCustomer(id); c.DoSomething(); }); } } </code></pre> <p>and then my interceptor can process the attributes for the class, but I can still instantiate the class using <code>new</code> and not worry about losing functionality.</p> <p>Is there a better way of using Unity interception, that doesn't force me to always use it for instantiating my objects?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload