Bạn đang xem: Dependency injection c# là gì
Bài Viết: Dependency injection c# là gì
Every example I come across on the mạng internet is implemented in C++ or C# or Java cùng it seems a little hard to follow those patterns in C.
Is there any examples that could give me a hint of how to make that work in C?
Applying SOLID is not always appropriate. Dependency inversion implies some indirection, cùng that typically means overhead. This kind of overhead is unlikely khổng lồ be appropriate in memory-constrained devices. But not all is lost: we can implement relevant OOP functionality in C, but we might also find that using the preprocessor provides enough flexibility.
A typical dependency inversion example refactors this kind of code:
class Dependency int concreteStuff;class Context Dependency d; void doSomething() print(d.concreteStuff); new Context(new Dependency()).doSomething();To:
interface Interface int getConcreteStuff();class Dependency implements Interface int concreteStuff; int getConcreteStuff() return this.concreteStuff; class Context Interface i; void doSomething() print(i.getConcreteStuff()); new Context(new Dependency()).doSomething();While C doesn”t have interfaces in the Java sense, one option is to lớn implement this OOP-like functionality (run-time polymorphism) ourselves:
// interface:typedef struct void* data; int (*getConcreteStuff)(Interface*); Interface;// dependency:typedef struct int concreteStuff; Dependency;static int getConcreteStuff(Interface* interface) return ((Dependency*)interface->data)->concreteStuff;Interface Dependency_new() Dependency* d = malloc(sizeof(*d)); d->concreteStuff = 0; return d, getConcreteStuff ;// context:typedef struct Interface i; Context;void Context_doSomething(Context* ctx) printf(“%dn”, ctx->i.getConcreteStuff(&ctx->i));// compositionContext ctx = Dependency_new() ;Context_doSomething(&ctx);The Interface represents a classic vtable that stores function pointers to lớn the interface methods. In simple cases where you only have a few function pointers you can bởi vì away with the explicit interface cùng store the pointers directly in the context. The context does not know anything about the concrete dependency, và only interacts with it through the interface function pointers – the actual dependency is hidden behind a void pointer. In all cases, the concrete dependency is resolved during composition, với can be freely selected at run time.
So this kind of approach is appropriate when you vày need the ability to select different dependencies at run time, or when you don”t know all possible interface implementations (e.g. When you are writing a library khổng lồ be extended by other applications).
But that kind of runtime flexibility is not always needed! Especially in an embedded context, you might be able to resolve the dependencies at build time cùng then flash the appropriate configuration. You also likely know all possible dependencies in advance. Then, the most C-ish approach is to use the preprocessor.
For example, you might use the preprocessor to select the correct definitions for structs và functions
#ifdef DEPENDENCY = “TEST” typedef struct Dependency; int getConcreteStuff(Dependency*) return 42; #else typedef struct int concreteStuff; Dependency; int getConcreteStuff(Dependency* d) return d->concreteStuff; #endiftypedef struct Dependency d; Context;void doSomething(Context* ctx) printf(“%dn”, getConcreteStuff(&ctx->d));Alternatively, you might compile all dependencies với use the preprocessor khổng lồ name the correct dependency:
// invoke compiler with -DDependency=TestDependency lớn use this implementationtypedef struct TestDependency;int TestDependency_getConcreteStuff(TestDependency*) return 42;typedef struct int concreteStuff; StandardDependency;int StandardDependency_getConcreteStuff(StandardDependency* d) return d->concreteStuff;// default to StandardDependency#ifndef Dependency#define Dependency StandardDependency#endif// helper to hotline functions with correct name#define METHOD(m) Dependency ## _ ## m;typedef struct Dependency d; Context;void doSomething(Context* ctx) printf(“%dn”, METHOD(getConcreteStuff)(&ctx->d));I prefer this latter approach because all the code is still compiled cùng type checked, thus guarding against bitrot. The extra generated machine code can be optimized away to save space, either if the dependency function are inline, have internal linkage, or by using links time optimization.
Bài Viết: Dependency Injection C# Là Gì, Dependency Injection In C# With Examples
Thể Loại: LÀ GÌ
Nguồn Blog là gì: https://ttmn.mobi Dependency Injection C# Là Gì, Dependency Injection In C# With Examples