ক্লাসে পরিষেবা কীভাবে ইনজেক্ট করবেন (উপাদান নয়)


91

আমি এমন কোনও ক্লাসে একটি পরিষেবা ইনজেকশন করতে চাই যা কোনও উপাদান নয়

উদাহরণ স্বরূপ:

মাইসারভাইস

import {Injectable} from '@angular/core';
@Injectable()
export class myService {
  dosomething() {
    // implementation
  }
}

আমার ক্লাস

import { myService } from './myService'
export class MyClass {
  constructor(private myservice:myService) {

  }
  test() {
     this.myservice.dosomething();
  }
}

এই সমাধানটি কাজ করে না (আমি মনে করি কারণ MyClassএখনও ইনস্ট্যান্ট করা হয়নি) been

কোনও ক্লাসে কোনও পরিষেবা ব্যবহার করার কোনও উপায় আছে (উপাদান নয়)? অথবা আপনি কি আমার কোড ডিজাইনটিকে অনুপযুক্ত হিসাবে বিবেচনা করবেন (কোনও শ্রেণীর মধ্যে কোনও পরিষেবা ব্যবহার করার জন্য যা উপাদান নয়)

ধন্যবাদ.

উত্তর:


57

ইনজেকশনগুলি কেবলমাত্র সেই ক্লাসগুলির সাথে কাজ করে যেগুলি অ্যাঙ্গুলার্স নির্ভরতা ইনজেকশন (ডিআই) দ্বারা ইনস্ট্যান্ট করা হয়।

  1. তোমার দরকার
    • যোগ @Injectable()করুন MyClassএবং
    • প্রদান MyClassমত providers: [MyClass]একটি উপাদান বা NgModule হবে।

আপনি যখন MyClassঅন্য কোথাও ইনজেক্ট করেন , ডিআই দ্বারা তা ইনস্ট্যান্ট MyServiceকরা MyClassহলে এটি নজিরটি পাস হয়ে যায় (এটি প্রথমবার ইনজেকশনের আগে)।

  1. একটি বিকল্প পদ্ধতির মত একটি কাস্টম ইনজেক্টর কনফিগার করা
constructor(private injector:Injector) { 
  let resolvedProviders = ReflectiveInjector.resolve([MyClass]);
  let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);

  let myClass : MyClass = childInjector.get(MyClass);
}

এই পদ্ধতি myClassএকটি হতে হবে MyClassউদাহরণস্বরূপ, Angulars Di দ্বারা instantiated এবং myServiceইনজেকশনের করা হবে MyClassযখন instantiated। কোনও নির্দেশিকার ভিতরে ম্যানুয়ালি ইনজেক্টর থেকে নির্ভরতা পাওয়াও
দেখুন

  1. তবুও অন্য একটি উপায় হ'ল উদাহরণটি নিজে তৈরি করা:
constructor(ms:myService)
let myClass = new MyClass(ms);

4
আমি মনে করি স্ট্যান্ডেলোন ক্লাসে ইনজেকশন পরিষেবাটি একটি বিরোধী-নিদর্শন।
টোমএক্সএক্সএক্স

11
অবশ্যই, তবে কখনও কখনও এটি এখনও উপলব্ধি করতে পারে এবং কী কী সম্ভব তা জেনে রাখা সর্বদা ভাল
গন্টার জ্যাচবাউয়ার

কেন কনস্ট্রাক্টরে নতুন ইনজেক্টর তৈরি করবেন? যেটা ইনজেকশন দেওয়া হয়েছিল তাকে কেন ব্যবহার করবেন না? আপনি যদি একটি নতুন তৈরি করতে চলেছেন তবে প্রথমে একটি ইনজেকশনের কোনও কারণ নেই
স্মাক 89

নতুনটি হ'ল অতিরিক্ত সরবরাহকারী সহ একটি শিশু ইনজেক্টর। যদি শিশু ইনজেক্টারে সংযোজিত সরবরাহকারীরা পিতা বা মাতা উপাদানগুলিতে বা মডিউল স্তরে সরবরাহ করা সরবরাহকারীর উপর নির্ভর করে, তবে ডিআই সমস্ত কিছুই স্বয়ংক্রিয়ভাবে সমাধান করতে পারে। অতএব নিশ্চিতভাবেই এমন পরিস্থিতি রয়েছে যেখানে এটি উপলব্ধি করে।
গন্টার জ্যাচবাউয়ার

4
@ টিমোথিপেনজ সম্পাদনার জন্য ধন্যবাদ। এই উদাহরণে এটি privateপ্রয়োজনীয় নয়, কারণ injectorনির্মাণকারীর বাইরে ব্যবহার করা হয়নি, সুতরাং কোনও ক্ষেত্রে একটি রেফারেন্স রাখার প্রয়োজন নেই।
Gternter Zöchbauer

30

প্রশ্নের সরাসরি উত্তর নয়, তবে আপনি যদি এই কারণটি পড়েন তবে আমি এটি হ'তে সাহায্য করতে পারে ...

ধরা যাক আপনি এনজি 2-অনুবাদ ব্যবহার করছেন এবং আপনি সত্যিই আপনার User.tsক্লাসটি এটি চান। আপনার তাত্ক্ষণিকভাবে ভাবা হ'ল ডিআই এটি inোকাতে ব্যবহার করুন, আপনি সর্বোপরি কৌণিক কাজ করছেন are তবে এটি এটিকে বোঝার মতো, আপনি এটি কেবল আপনার নির্মাত্রে পাস করতে পারেন, বা এটি উপাদান থেকে সেট করা একটি সর্বজনীন পরিবর্তনশীল করতে পারেন (যেখানে আপনি সম্ভবত এটি ডিআই করেছিলেন) DI

যেমন:

import { TranslateService } from "ng2-translate";

export class User {
  public translateService: TranslateService; // will set from components.

  // a bunch of awesome User methods
}

তারপরে অনুবাদকর্মকে সংক্রামিত কিছু ব্যবহারকারীর সাথে সম্পর্কিত উপাদান থেকে

addEmptyUser() {
  let emptyUser = new User("", "");
  emptyUser.translateService = this.translateService;
  this.users.push(emptyUser);
}

আশা করি এটি আমার মতো তাদের যারা তাদের কোড বজায় রাখতে অনেক বেশি লেখার বিষয়ে লেখালেখি করতে সহায়তা করে কারণ আমরা মাঝে মাঝে খুব চালাক হয়েছি =]

(দ্রষ্টব্য: আপনার কনস্ট্রাক্টর পদ্ধতির অংশ হিসাবে পরিবর্তনের পরিবর্তে আপনি কোনও ভেরিয়েবল সেট করতে চাইতে পারেন যে কারণে আপনার পরিষেবাটি ব্যবহার করার দরকার নেই এমন ক্ষেত্রে আপনার থাকতে পারে, তাই সর্বদা এটি পাস করার প্রয়োজন হয় অতিরিক্ত আমদানি প্রবর্তন করার অর্থ / কোড যা সত্যই ব্যবহৃত হয় না)


এবং সম্ভবত এমন translateServiceএকটি getগেট / সেট করুন যেখানে আপনি সেট করতে ভুলে গেলে নুলরেফারেন্স ব্যতিক্রমের পরিবর্তে অর্থবহ ত্রুটি ছুড়ে দেয়
সাইমন_উইভার

4
ক্লাস কন্সট্রাক্টরে ট্রান্সলেটস সার্ভিসকে প্রয়োজনীয় প্যারাম বানানো আরও বোধগম্য হতে পারে? এই প্যাটার্নটি ডিআই প্যাটার্নের সাথে আরও উপযুক্ত im
আইসাইকুল

16

এটি ধরণের ( খুব ) হ্যাকি, তবে আমি ভেবেছিলাম আমার সমাধানটিও ভাগ করে নেব। মনে রাখবেন যে এটি কেবলমাত্র সিঙ্গেলটন পরিষেবাগুলির সাথে কাজ করবে (অ্যাপ্লিকেশন রুটে ইঞ্জেকশন করা হয়েছে, উপাদান নয়!), যেহেতু তারা আপনার অ্যাপ্লিকেশন হিসাবে দীর্ঘকাল বেঁচে থাকে এবং এর মধ্যে কেবল একটি উদাহরণ রয়েছে।

প্রথমত, আপনার পরিষেবাতে:

@Injectable()
export class MyService {
    static instance: MyService;
    constructor() {
        MyService.instance = this;
    }

    doSomething() {
        console.log("something!");
    }
}

তারপরে যে কোনও ক্লাসে:

export class MyClass {
    constructor() {
        MyService.instance.doSomething();
    }
}

এই কোডটি ভাল যদি আপনি কোড বিশৃঙ্খলা হ্রাস করতে চান এবং যে কোনও উপায়ে নন-সিঙ্গলটন পরিষেবা ব্যবহার করছেন না।


তবে কনস্ট্রাক্টরের কোনও ঘোষণা ছাড়াই আপনি মাই ক্লাসে মাই সার্ভিসটি কীভাবে ব্যবহার করবেন?
আখিল ভি

@ অখিলভ আপনি কেবলমাত্র মাই সার্ভিসটি আমদানি করুন যেমন আপনি অন্য কোনও শ্রেণি আমদানি করেন, তারপরে আপনি বর্ণিত পদ্ধতিতে সরাসরি কল করতে পারেন।
কিলভস

13

locator.service.ts

import {Injector} from "@angular/core";

export class ServiceLocator {
    static injector: Injector;
}

app.module.ts

@NgModule({ ... })

export class AppModule {
    constructor(private injector: Injector) {
        ServiceLocator.injector = injector;
    }
 }

poney.model.ts

export class Poney {

    id: number;
    name: string;
    color: 'black' | 'white' | 'brown';

    service: PoneyService = ServiceLocator.injector.get(PoneyService); // <--- HERE !!!

    // PoneyService is @injectable and registered in app.module.ts
}

4
ওপি-র দৃশ্যের জন্য সেরা অনুশীলন কী তা নিশ্চিত নন, তবে এই উত্তরটি নেতৃস্থানীয়দের চেয়ে অনেক সহজ বলে মনে হচ্ছে। injector.get()মডিউলের কাজের জন্য কলটি সরানো হবে (স্টেটলেস পরিষেবাটি ধরে নিলে যাতে বেশ কয়েকটি ক্লাস একই উদাহরণ "ভাগ" করতে পারে)?
G0BLiN

আমি মনে করি যে কোডটি সমস্ত পেনি দৃষ্টান্তগুলির মাধ্যমে পেনি পরিষেবার একই উদাহরণ ভাগ করে নেবে। আপনি কি মনে করেন?
জুলিয়েন

জুলিয়েন - এটি আমার দৃশ্যের জন্য একটি গ্রহণযোগ্য ফলাফল (প্রকৃতপক্ষে পছন্দসই) - কোনও ইনপুট বৈধকরণকারক, ব্যবহারকারীর অনুমতি হ্যান্ডলার বা স্থানীয়করণ পরিষেবার মতো কিছু মনে করুন - যেখানে অ্যাপ্লিকেশনটিতে আপনার একই কার্যকারিতা প্রয়োজন তবে প্রত্যেকটির জন্য একটি অনন্য উদাহরণের প্রয়োজন নেই পরিষেবা স্বতন্ত্র গ্রাহক।
G0BLiN

জেসমিন টেস্টে এটি কাজ করার চেষ্টা করতে কিছুটা সমস্যা হচ্ছে। কিভাবে পরীক্ষা সেটআপ কনফিগার করবেন? সার্ভিসলোকেটার.ইনজেক্টর নালায় ফিরতে থাকে, যদিও আমি "পনি সার্ভিস" টেস্টবেডে ইনজেকশন দিয়েছি?
জিগিজমস

3

যদি আপনার পরিষেবার পদ্ধতিগুলি খাঁটি ফাংশন হয় তবে এটি সমাধানের একটি পরিষ্কার উপায় হ'ল আপনার সেবার স্থিতিশীল সদস্য।

আপনার সেবা

import {Injectable} from '@angular/core';
@Injectable()
export class myService{
  public static dosomething(){
    //implementation => doesn't use `this`
  }
}

তোমার শ্রেণী

export class MyClass{
  test(){
     MyService.dosomething(); //no need to inject in constructor
  }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.