আমি কৌনিক 2 এ কীভাবে একটি সিঙ্গলটন পরিষেবা তৈরি করব?


142

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

আমার ফেসবুক সার্ভিস রয়েছে যা আমি ফেসবুক জাভাস্ক্রিপ্ট এপিআই এবং ফেসবুক সার্ভিস ব্যবহার করে এমন একটি ইউজার সার্ভিস কল করতে ব্যবহার করি। আমার বুটস্ট্র্যাপটি এখানে:

bootstrap(MainAppComponent, [ROUTER_PROVIDERS, UserService, FacebookService]);

আমার লগিং থেকে দেখে মনে হচ্ছে বুটস্ট্র্যাপ কলটি শেষ হয়ে গেছে, তারপরে আমি দেখি প্রতিটি কনস্ট্রাক্টরের কোড চালুর আগেই ফেসবুক সার্ভিস ইউজার সার্ভিস তৈরি হচ্ছে, মেইনএপকম্পোনেন্ট, হেডারকম্পোনেন্ট এবং ডিফল্ট কম্পোনেন্ট:

এখানে চিত্র বর্ণনা লিখুন


8
আপনি কি নিশ্চিত যে আপনি আছে করছি না যোগ UserServiceএবং FacebookServiceকরতে providersকোথাও?
গন্টার জ্যাচবাউয়ার

উত্তর:


132

জেসন পুরোপুরি ঠিক! এটি নির্ভরতা ইনজেকশন যেভাবে কাজ করে তার কারণেই। এটি হায়ারারিকাল ইনজেক্টরগুলির উপর ভিত্তি করে।

একটি কৌণিক 2 অ্যাপ্লিকেশনের মধ্যে বেশ কয়েকটি ইঞ্জেক্টর রয়েছে:

  • আপনার অ্যাপ্লিকেশনটি বুটস্ট্র্যাপ করার সময় আপনি যে মূলটি কনফিগার করেছেন সেগুলি
  • উপাদান হিসাবে প্রতি ইনজেক্টর। যদি আপনি অন্য একটির ভিতরে কোনও উপাদান ব্যবহার করেন। উপাদান ইনজেক্টর পিতা বা মাতা উপাদানগুলির একটি শিশু। অ্যাপ্লিকেশন উপাদান (আপনার অ্যাপ্লিকেশন বুস্ট্র্যাপিংয়ের সময় আপনি যেটিকে নির্দিষ্ট করেছেন) এর প্যারেন্ট হিসাবে মূল ইঞ্জেকটর রয়েছে।

যখন কৌনিক 2 কম্পোনেন্ট কনস্ট্রাক্টারে কিছু ইনজেক্ট করার চেষ্টা করে:

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

সুতরাং আপনি যদি পুরো অ্যাপ্লিকেশনটির জন্য একটি সিঙ্গলটন পেতে চান তবে আপনার অবশ্যই সরবরাহকারীর মূল সংক্রমক বা অ্যাপ্লিকেশন উপাদান ইনজেক্টরের স্তরে সংজ্ঞায়িত করতে হবে।

তবে কৌণিক 2 নীচ থেকে ইনজেক্টর গাছের দিকে তাকিয়ে থাকবে। এর অর্থ হ'ল সর্বনিম্ন স্তরে সরবরাহকারী ব্যবহার করা হবে এবং সম্পর্কিত উদাহরণের সুযোগটি এই স্তরটি হবে।

আরও তথ্যের জন্য এই প্রশ্নটি দেখুন:


1
ধন্যবাদ, এটি এটি ভালভাবে ব্যাখ্যা করে। এটি আমার পক্ষে কেবল স্ব-স্বজ্ঞাত ছিল কারণ সেই ধরণেরটি কৌণিক 2 এর স্ব-অন্তর্ভুক্ত উপাদান দৃষ্টান্তের সাথে ভেঙে যায়। সুতরাং আসুন আমি বলি যে আমি ফেসবুকের জন্য উপাদানগুলির একটি গ্রন্থাগার তৈরি করছি, তবে আমি তাদের সকলকে একটি সিঙ্গলটন পরিষেবা ব্যবহার করতে চাই। লগ ইন করা ব্যবহারকারীর প্রোফাইল ছবি দেখাতে এবং অন্য একটি পোস্ট করার জন্য একটি উপাদান থাকতে পারে। এই উপাদানগুলি ব্যবহার করে এমন অ্যাপ্লিকেশনটিতে পরিষেবাটি নিজেই ব্যবহার না করে এমনকি ফেসবুক পরিষেবাটি সরবরাহকারীর হিসাবে অন্তর্ভুক্ত করতে হবে? আমি কেবলমাত্র 'getInstance ()' পদ্ধতির সাহায্যে একটি পরিষেবা ফিরিয়ে দিতে পারি যা আসল পরিষেবার
এককটি

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

এত বোকা হওয়ার জন্য দুঃখিত তবে আমার পক্ষে এটি পরিষ্কার নয় যে আপনি কীভাবে একটি সিঙ্গলটন পরিষেবা তৈরি করেন, আপনি আরও বিশদভাবে ব্যাখ্যা করতে পারেন?
gyozo kudor

সুতরাং, কোনও পরিষেবার একক দৃষ্টান্তের সাথে কাজ করার জন্য, এটি অ্যাপ.মডিউল.টিসে বা অ্যাপ.কম্পোনেন্ট.টিসে সরবরাহকারী হিসাবে ঘোষণা করা উচিত?
ব্যবহারকারী 1767316

প্রতিটি অ্যাপ্লিকেশন.মডিউল.টসে প্রতিটি পরিষেবা ঘোষনা করা আমার পক্ষে কাজটি করেছে।
ব্যবহারকারী 1767316

142

আপডেট (কৌণিক 6 +)

সিঙ্গলটন পরিষেবা তৈরির প্রস্তাবিত উপায়টি পরিবর্তিত হয়েছে। এখন @Injectableপরিষেবাটিতে ডেকরেটারে এটি নির্দিষ্ট করার পরামর্শ দেওয়া হচ্ছে যে এটি 'রুট' এ সরবরাহ করা উচিত। এটি আমার কাছে প্রচুর পরিমাণে উপলব্ধি করে এবং আপনার মডিউলগুলিতে প্রদত্ত সমস্ত পরিষেবাগুলির আর কোনও তালিকা করার দরকার নেই। আপনার যখন প্রয়োজন পরিষেবাগুলি দরকার তখন আপনি কেবল তা আমদানি করুন এবং তারা যথাযথ জায়গায় নিবন্ধন করুন। আপনি একটি মডিউলও নির্দিষ্ট করতে পারেন তাই মডিউলটি আমদানি করা হলে কেবল এটি সরবরাহ করা হবে।

@Injectable({
  providedIn: 'root',
})
export class ApiService {
}

আপডেট (কৌণিক 2)

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

CoreModule.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ApiService } from './api.service';

@NgModule({
    imports: [
        CommonModule
    ],
    exports: [ // components that we want to make available
    ],
    declarations: [ // components for use in THIS module
    ],
    providers: [ // singleton services
        ApiService,
    ]
})
export class CoreModule { }

AppModule.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';

@NgModule({
    declarations: [ AppComponent ],
    imports: [
        CommonModule,
        CoreModule // will provide ApiService
    ],
    providers: [],
    bootstrap: [ AppComponent ]
})
export class AppModule { }

আসল উত্তর

আপনি যদি কোনও সরবরাহকারীকে এখানে bootstrap()তালিকাভুক্ত করেন তবে আপনার সেগুলি আপনার উপাদান ডেকরেটারে তালিকাভুক্ত করার দরকার নেই:

import { ApiService } from '../core/api-service';

@Component({
    selector: 'main-app',
    templateUrl: '/views/main-app.html',
    // DO NOT LIST PROVIDERS HERE IF THEY ARE IN bootstrap()!
    // (unless you want a new instance)
    //providers: [ApiService]
})
export class MainAppComponent {
    constructor(private api: ApiService) {}
}

প্রকৃতপক্ষে আপনার সরবরাহকারীদের শ্রেণিতে তালিকাভুক্তকরণ এটির একটি নতুন উদাহরণ তৈরি করে, যদি কোনও পিতামাতার উপাদান ইতিমধ্যে এটি তালিকাভুক্ত করে তবে বাচ্চাদের প্রয়োজন হয় না এবং তারা যদি তা করে তবে তারা একটি নতুন উদাহরণ পাবে।


1
এখন (জানুয়ারী 2017) হিসাবে, আপনি ঠিক [providers]আপনার মডিউল ফাইলের মধ্যে পরিষেবাটি তালিকাভুক্ত করবেন , তাই না bootstrap()?
জেসন সোয়েট

5
কেন করা ApiServiceমধ্যে AppModuleএর providers, এবং এইভাবে প্রয়োজনীয়তার এড়াতে CoreModule? (@ জেসনসওয়েট পরামর্শ দিচ্ছেন এটি নিশ্চিত নয়)
জান

1
@ জেসনগোম্যাট আপনি কীভাবে উপাদানটিতে এটি ব্যবহার করবেন উদাহরণটি যোগ করতে পারেন? আমরা ApiServiceশীর্ষেটি আমদানি করতে পারতাম তবে কেন কেন এটিকে কোরমোডুলের সরবরাহকারী অ্যারেতে রাখার এবং তারপর অ্যাপ্লিকেশন মডেলটিতে সেইটিকে আমদানি করার জন্য কেন বিরক্ত করব ... এটি এখনও আমার জন্য ক্লিক করেনি।
হোগান

সুতরাং, পরিষেবাটি মডিউল সরবরাহকারীর উপর স্থাপন করা সেই মডিউলটির জন্য একটি সিঙ্গলটন সরবরাহ করবে। এবং কম্পোনেন্ট সরবরাহকারীগুলিতে পরিষেবা স্থাপন করা উপাদানটির প্রতিটি উদাহরণের জন্য একটি নতুন উদাহরণ তৈরি করবে? এটা কি সঠিক?
BrunoLM

@ ব্রুনোএলএম কী ঘটছে তা দেখানোর জন্য আমি একটি পরীক্ষা অ্যাপ তৈরি করেছি । আকর্ষণীয় যে যদিও TestServiceমূল এবং অ্যাপ্লিকেশন মডিউল উভয় ক্ষেত্রেই সুনির্দিষ্ট করা হলেও মডিউলগুলির জন্য দৃষ্টান্তগুলি তৈরি করা হয় না কারণ এটি উপাদান দ্বারা সরবরাহ করা হয় যাতে কৌণিক কখনই ইনজেক্টর গাছের উপরে উঠে যায় না। সুতরাং আপনি যদি নিজের মডিউলে কোনও পরিষেবা সরবরাহ করেন এবং এটি কখনই ব্যবহার না করেন তবে কোনও উদাহরণ তৈরি হবে বলে মনে হয় না।
জেসন গোয়েমাট

24

আমি জানি কৌণিকের থিয়েরির মতো হায়ারার্কিকাল ইনজেক্টর রয়েছে।

তবে আপনি এখানে এমন কোনও ব্যবহারের সন্ধান পান যেখানে আপনি সত্যিই পিতামাতার কাছে এটি ইনজেক্ট করতে চান না এমন ক্ষেত্রে আমার কাছে আরও একটি বিকল্প রয়েছে।

আমরা পরিষেবার একটি উদাহরণ তৈরি করে তা অর্জন করতে পারি এবং সর্বদা তা সরবরাহ করে on

import { provide, Injectable } from '@angular/core';
import { Http } from '@angular/core'; //Dummy example of dependencies

@Injectable()
export class YourService {
  private static instance: YourService = null;

  // Return the instance of the service
  public static getInstance(http: Http): YourService {
    if (YourService.instance === null) {
       YourService.instance = new YourService(http);
    }
    return YourService.instance;
  }

  constructor(private http: Http) {}
}

export const YOUR_SERVICE_PROVIDER = [
  provide(YourService, {
    deps: [Http],
    useFactory: (http: Http): YourService => {
      return YourService.getInstance(http);
    }
  })
];

এবং তারপরে আপনার উপাদানটিতে আপনি আপনার কাস্টম সরবরাহ পদ্ধতি ব্যবহার করেন।

@Component({
  providers: [YOUR_SERVICE_PROVIDER]
})

শ্রেণিবদ্ধ ইনজেক্টরগুলির উপর নির্ভর করে আপনার একটি সিঙ্গলটন পরিষেবা থাকা উচিত।

আমি বলছি না এটি একটি ভাল উপায়, ঠিক এমন ক্ষেত্রে যদি কারওর সমস্যা হয় যেখানে শ্রেণিবদ্ধ ইনজেক্টরগুলি সম্ভব না হয়।


1
করা উচিত SHARE_SERVICE_PROVIDERহবে YOUR_SERVICE_PROVIDERউপাদানের? এছাড়াও আমি ধরে নিচ্ছি যে সার্ভিস ফাইলটি আমদানি করা স্বাভাবিকের মতো প্রয়োজন এবং কনস্ট্রাক্টরের এখনও 'ইয়োর সার্ভিস' টাইপের একটি প্যারামিটার থাকবে, তাই না? আমার মনে হয় এটি আমার পছন্দ হয়েছে, আপনাকে একটি একক গ্যারান্টির গ্যারান্টি দেয় এবং পরিষেবাটি স্তরক্রমটি সরবরাহ করা হয় তা নিশ্চিত করে না। এটি স্বতন্ত্র উপাদানগুলিকে কেবল providersসিঙ্গলটন সরবরাহকারীর পরিবর্তে পরিষেবাটি তালিকাভুক্ত করে নিজের কপিটি পেতে দেয় ?
জেসন গোয়েমাত

@ জেসনগোম্যাট আপনি ঠিক বলেছেন সম্পাদিত। ঠিক, আপনি এটি কন্সট্রাকটর ঠিক একই ভাবে এবং আপনি যোগ করে উপাদানের সরবরাহকারীদের উপর না YOUR_SERVICE_PROVIDER। হ্যাঁ, সমস্ত সরবরাহকারী কেবল এটি সরবরাহকারীর মধ্যে যুক্ত করে একই উদাহরণ পাবেন।
জোয়েল আলমেডা

কোনও বিকাশকারী এটি ব্যবহার করার সময়, তারা ঠাঁইকে জিজ্ঞাসা করা উচিত "আমি কেন এঙ্গুলার ব্যবহার করছি কেন যদি আমি এই পরিস্থিতির জন্য কৌণিকর যে পদ্ধতিগুলি সরবরাহ করে তা ব্যবহার না করি?" অ্যাপ্লিকেশন পর্যায়ে পরিষেবা সরবরাহ করানো কৌণিক প্রসঙ্গে প্রতিটি পরিস্থিতির জন্য পর্যাপ্ত হওয়া উচিত।
RyNo

1
+1 যদিও এটি সিঙ্গলটন পরিষেবাদি তৈরির একটি উপায় এটি একটি মাল্টিটন পরিষেবা তৈরির একটি উপায় হিসাবে কেবল instanceসম্পত্তিটিকে উদাহরণস্বরূপের মূল-মানচিত্রে
রূপান্তরিত করে

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

16

সিনট্যাক্স পরিবর্তন করা হয়েছে। এই লিঙ্কটি পরীক্ষা করুন

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

পদক্ষেপ 1. @ ইনজেক্টেবল ডেকরেটর দিয়ে সিঙ্গলটন ক্লাস তৈরি করুন

@Injectable()
export class HeroService {
  getHeroes() { return HEROES;  }
}

পদক্ষেপ 2. কনস্ট্রাক্টর ইনজেক্ট

export class HeroListComponent { 
  constructor(heroService: HeroService) {
    this.heroes = heroService.getHeroes();
  }

পদক্ষেপ 3. রেজিস্টার প্রদানকারী

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    routing,
    HttpModule,
    JsonpModule
  ],
  declarations: [
    AppComponent,
    HeroesComponent,
    routedComponents
  ],
  providers: [
    HeroService
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule { }

আমার Injectableক্লাসটি যদি পরিষেবা না হয় এবং staticবিশ্বব্যাপী ব্যবহারের জন্য কেবল স্ট্রিং থাকে তবে কী হবে?
সৈয়দ আলী তাকি

2
এই সরবরাহকারীদের মতো: [{সরবরাহ: 'API_URL', ব্যবহারভ্যালু: ' coolapi.com '}]
হুইশার

7

যোগ করার পদ্ধতি @Injectableসার্ভিস প্রসাধক, এবং রুট মডিউল একটি প্রদানকারী এটি একটি Singleton করতে হবে যেমন নিবন্ধনের।


আমি যদি এটি বুঝতে পারি তবে আমাকে বলুন। যদি আপনি যা বলেছি তা আমি যদি করি তবে ঠিক আছে, এটি সিঙ্গলটন হবে। যদি, এছাড়াও, পরিষেবাটি অন্য মডিউলে সরবরাহকারীও হয় তবে এটি আর সিঙ্গলটন থাকবে না, তাই না? শ্রেণিবিন্যাসের কারণে।
হারিংগার

1
এবং সরবরাহকারীগুলিকে পৃষ্ঠাগুলির @ বিভাগীয় সজ্জাতে নিবন্ধন করবেন না।
লওরা

@Laura। আমি কি এখনও কি এমন উপাদানগুলিতে আমদানি করি যা প্রকৃতপক্ষে পরিষেবাটি ব্যবহার করে?
চিহ্নিত করুন

@ মার্ক হ্যাঁ, আপনার এটি আমদানি করা দরকার এবং তারপরে আপনাকে কেবল এটির constructorমতো ঘোষণা করতে হবে : import { SomeService } from '../../services/some/some'; @Component({ selector: 'page-selector', templateUrl: 'page.html', }) export class SomePage { constructor( public someService: SomeService ) { }
লরা

6

এটি আমার পক্ষে ভাল কাজ করছে বলে মনে হচ্ছে

@Injectable()
export class MyStaticService {
  static instance: MyStaticService;

  constructor() {
    return MyStaticService.instance = MyStaticService.instance || this;
  }
}

8
আমি এটিকে একটি এঙ্গুলার 2 অ্যান্টি-প্যাটার্ন বলব। পরিষেবাটি সঠিকভাবে সরবরাহ করুন এবং Angular2 সর্বদা একই দৃষ্টিতে ইনজেক্ট করবে। আরও দেখুন stackoverflow.com/questions/12755539/...
গুন্টার Zöchbauer

3
@ গন্টার জ্যাচবাউয়ার, দয়া করে "পরিষেবাটি সঠিকভাবে সরবরাহ করুন এবং অ্যাঙ্গুলার 2 সর্বদা একই উদাহরণটি ইনজেক্ট করবে" সম্পর্কিত কিছু পরামর্শ দিতে পারেন। ? কারণ এটি অস্পষ্টভাবে এবং আমি গুগল করে কোনও দরকারী তথ্য খুঁজে পাইনি।
এখন

আমি শুধু এই উত্তর, পোস্ট যে আপনার প্রশ্নের সঙ্গে যথাসাধ্য সাহায্যের stackoverflow.com/a/38781447/217408 (এছাড়াও লিংক সেখানে দেখতে)
গুন্টার Zöchbauer

2
এটি নিখুঁত। আপনার অ্যাংগুলারগুলির নিজস্ব নির্ভরতা ইনজেকশন ব্যবহার করা উচিত , তবে আপনি যখন এটি প্রত্যাশা করেন তখন আপনার পরিষেবাটি সিঙ্গলটনই একেবারে নিশ্চিত হওয়ার জন্য এই প্যাটার্নটি ব্যবহার করার কোনও ক্ষতি নেই। আপনি দু'টি পৃথক স্থানে একই পরিষেবাটি ইনজেক্ট করার কারণে সম্ভবত বাগগুলির জন্য শিকারের প্রচুর সময় সাশ্রয় হয়।
পলমল্লো

আমি এই নিদর্শনটি ব্যবহার করেছিলাম তা জানার জন্য যে সমস্যার মুখোমুখি আমি হচ্ছিলাম সেবার কারণটি সিঙ্গলটন না হওয়ার কারণে হয়েছিল
hr-tis

5

এখানে কৌনিক সংস্করণ ২.৩ সহ একটি কার্যকরী উদাহরণ রয়েছে। এই কনস্ট্রাক্টরের মতো কেবল পরিষেবাটির নির্মাতাকে স্ট্যান্ড উপায়ে কল করুন (বেসরকারী _ ব্যবহারকারীর সেবা: ব্যবহারকারীর সেবা)। এবং এটি অ্যাপটির জন্য একটি সিঙ্গলটন তৈরি করবে।

user.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Subject }    from 'rxjs/Subject';
import { User } from '../object/user';


@Injectable()
export class UserService {
    private userChangedSource;
    public observableEvents;
    loggedUser:User;

    constructor() {
       this.userChangedSource = new Subject<any>();
       this.observableEvents = this.userChangedSource.asObservable();
    }

    userLoggedIn(user:User) {
        this.loggedUser = user;
        this.userChangedSource.next(user);
    }

    ...
}

app.component.ts

import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { UserService } from '../service/user.service';
import { User } from '../object/user';

@Component({
    selector: 'myApp',
    templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
    loggedUser:User;

    constructor(private _userService:UserService) { 
        this._userService.observableEvents.subscribe(user => {
                this.loggedUser = user;
                console.log("event triggered");
        });
    }
    ...
}

4

singleton serviceহ'ল এমন একটি পরিষেবা যার জন্য অ্যাপ্লিকেশনটিতে কেবলমাত্র একটি উদাহরণ উপস্থিত রয়েছে।

আছে (2) উপায়ে আপনার অ্যাপ্লিকেশনের জন্য একটি Singleton সেবা প্রদান।

  1. providedInসম্পত্তি ব্যবহার করুন , বা

  2. AppModuleঅ্যাপ্লিকেশনটির সরাসরি মডিউল সরবরাহ করুন

সরবরাহকৃত ব্যবহার

কৌণিক 6.0 দিয়ে শুরু করে, সিঙ্গলটন পরিষেবা তৈরির পছন্দের উপায়টি হ'ল providedInপরিষেবাটির @Injectable()সাজসজ্জারকে রুট করা । এটি কৌনিকটি অ্যাপ্লিকেশন রুটে পরিষেবা সরবরাহ করতে বলে।

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

এনজিএমডিউল সরবরাহকারী অ্যারে

.0.০ এর আগে কৌণিক সংস্করণ সহ নির্মিত অ্যাপ্লিকেশনগুলিতে, পরিষেবাদিগুলিকে নিম্নরূপে এনজিডমডুল সরবরাহকারী অ্যারেগুলি নিবন্ধিত করা হয়:

@NgModule({
  ...
  providers: [UserService],
  ...
})

যদি NgModuleএটি মূলে থাকে AppModuleতবে ব্যবহারকারীর সার্ভিসটি একটি সিঙ্গলটন এবং অ্যাপ্লিকেশন জুড়ে উপলব্ধ। যদিও আপনি এটি এটিকে কোডিং করে দেখতে পাচ্ছেন তবে পরিষেবাটিতে ডেকরেটারের providedInসম্পত্তি ব্যবহার করা @Injectable()নিজেই কৌণিক 6.0 এর চেয়ে বেশি পছন্দনীয় কারণ এটি আপনার পরিষেবাগুলিকে গাছকে কাঁপানোর মতো করে তোলে।


3

আপনি useValueসরবরাহকারী ব্যবহার করতে পারেন

import { MyService } from './my.service';

@NgModule({
...
  providers: [ { provide: MyService, useValue: new MyService() } ],
...
})

5
useValueসিঙ্গলটনের সাথে সম্পর্কিত নয়। ইউজভ্যালু কেবলমাত্র একটি Type( useClass) পরিবর্তে ডিআই কল newকরে useFactoryযেখানে কোনও ফাংশনটি পাস হয় যেখানে ডিআই দ্বারা ডাকলে মানটি ফেরত দেয় তার পরিবর্তে একটি মান পাস করতে হয়। কৌণিক ডিআই স্বয়ংক্রিয়ভাবে প্রতিটি সরবরাহকারীর জন্য একক উদাহরণ বজায় করে। কেবল একবার এটি সরবরাহ করুন এবং আপনার একটি সিঙ্গলটন রয়েছে। দুঃখিত, আমাকে ডাউনওয়েট করতে হবে কারণ এটি কেবল অবৈধ তথ্য: - /
গন্টার জ্যাচবাউয়ার

3

কৌণিক @ 6 থেকে, আপনি থাকতে পারে providedInএকটি ইন Injectable

@Injectable({
  providedIn: 'root'
})
export class UserService {

}

ডক্স এখানে পরীক্ষা করুন

কৌনিকটিতে একটি পরিষেবাকে একক করার দুটি উপায় রয়েছে:

  1. অ্যাপ্লিকেশন রুটে পরিষেবাটি সরবরাহ করা উচিত তা ঘোষণা করুন।
  2. অ্যাপমোডুলে বা এমন একটি মডিউলে পরিষেবা অন্তর্ভুক্ত করুন যা কেবলমাত্র অ্যাপমডিউল দ্বারা আমদানি করা হয়।

কৌণিক 6.0 দিয়ে শুরু করে, একটি সিঙ্গলটন পরিষেবাদি তৈরি করার পছন্দের উপায়টি পরিষেবাটিতে নির্দিষ্ট করে দেওয়া উচিত যে এটি অ্যাপ্লিকেশন রুটে সরবরাহ করা উচিত। এটি সার্ভিসের @ ইনজেক্টেবল ডেকরেটারে রুট করার জন্য সরবরাহকারীর সেট করে এটি করা হয়:


এটি ভাল, তবে আপনার ভেরিয়েবলগুলি না থাকার সাথে অপ্রত্যাশিত সমস্যাও থাকতে পারে যা কিছু আইটেম ঘোষণা করে সমাধান করা যেতে পারে public static
সিজেবার্থ

2

কেবলমাত্র app.module.ts এ আপনার পরিষেবা সরবরাহকারীর হিসাবে ঘোষণা করুন।

এটা আমার জন্য কাজ করেছে।

providers: [Topic1Service,Topic2Service,...,TopicNService],

তারপরে হয় এটি নির্মাণকারীর ব্যক্তিগত প্যারামিটার ব্যবহার করে ইনস্ট্যান্সিয়েট করুন:

constructor(private topicService: TopicService) { }

বা যেহেতু আপনার পরিষেবাটি এইচটিএমএল থেকে ব্যবহৃত হয়, তাই-প্রড বিকল্পটি দাবি করবে:

Property 'topicService' is private and only accessible within class 'SomeComponent'.

আপনার সেবার জন্য একজন সদস্য যুক্ত করুন এবং এটি কনস্ট্রাক্টরের পুনরুদ্ধারের উদাহরণটি পূরণ করুন:

export class SomeComponent {
  topicService: TopicService;
  constructor(private topicService: TopicService) { 
    this.topicService= topicService;
  }
}

0
  1. আপনি যদি অ্যাপ্লিকেশন পর্যায়ে পরিষেবা সিঙ্গলটন বানাতে চান তবে আপনার এটিকে app.module.ts এ সংজ্ঞায়িত করা উচিত

    সরবরাহকারীরা: [মাই অ্যাপ্লিকেশনসেবর্স] (আপনি শিশু মডিউলে একইরূপ নির্ধারণ করতে পারবেন সেইটিকে মডিউলটি নির্দিষ্ট করে তোলার জন্য)

    • এই পরিষেবা সরবরাহকারীর সাথে যুক্ত করবেন না যা সেই উপাদানটির জন্য একটি দৃষ্টান্ত তৈরি করে যা সিঙ্গেলটন ধারণাটি ভেঙে দেয়, কেবল কনস্ট্রাক্টরের মাধ্যমে ইনজেকশন দেয়।
  2. আপনি যদি উপাদান স্তর তৈরি পরিষেবাতে সিঙ্গলটন পরিষেবা সংজ্ঞায়িত করতে চান তবে সেই পরিষেবাটি app.module.ts এ যুক্ত করুন এবং সুনিপেটের নীচে স্নিপেটে দেখানো হিসাবে নির্দিষ্ট উপাদানটির ভিতরে সরবরাহকারী অ্যারে যুক্ত করুন।

    @ কম্পোনেন্ট ({নির্বাচক: 'অ্যাপ-রুট', টেম্পলেট ইউআরএল: '।

  3. কৌণিক 6 অ্যাপ্লিকেশন পর্যায়ে পরিষেবা যুক্ত করার নতুন উপায় সরবরাহ করে। AppModule এ সরবরাহকারীদের [] অ্যারেতে পরিষেবা শ্রেণি যুক্ত করার পরিবর্তে আপনি @Injectable () এ নিম্নলিখিত কনফিগারেশন সেট করতে পারেন:

    @ ইনজেক্টেবল ({প্রদত্তIn: 'রুট'}) এক্সপোর্ট ক্লাস মাই সার্ভিস {...}

"নতুন সিনট্যাক্স" এর একটি সুবিধা দেয় যদিও: পরিষেবাগুলি অ্যাঙ্গুলার (পর্দার পিছনে) দ্বারা অলসভাবে লোড করা যায় এবং অপ্রয়োজনীয় কোড স্বয়ংক্রিয়ভাবে সরানো যায়। এটি আরও ভাল পারফরম্যান্স এবং লোডিং গতির দিকে নিয়ে যেতে পারে - যদিও এটি সাধারণভাবে বড় পরিষেবা এবং অ্যাপ্লিকেশনগুলিকে কেবলমাত্র লাথি দেয়।


0

উপরের চমৎকার উত্তরের পাশাপাশি, অন্য কিছু থাকতে পারে যা যদি আপনার সিঙ্গলটনের জিনিসগুলি এখনও সিঙ্গলটন হিসাবে আচরণ না করে তবে অনুপস্থিত। সিঙ্গেলটনে কোনও পাবলিক ফাংশন কল করার সময় এবং এটি ভুল ভেরিয়েবলগুলি ব্যবহার করছে তা আবিষ্কার করার সময় আমি এই সমস্যার মধ্যে পড়েছিলাম। দেখা যাচ্ছে যে সমস্যাটি thisসিঙ্গলটনের কোনও পাবলিক কার্যাবলির জন্য সিঙ্গলটনের সাথে আবদ্ধ থাকার গ্যারান্টিযুক্ত নয়। এখানে পরামর্শ মত অনুসরণ করে এটি সংশোধন করা যেতে পারে :

@Injectable({
  providedIn: 'root',
})
export class SubscriptableService {
  public serviceRequested: Subject<ServiceArgs>;
  public onServiceRequested$: Observable<ServiceArgs>;

  constructor() {
    this.serviceRequested = new Subject<ServiceArgs>();
    this.onServiceRequested$ = this.serviceRequested.asObservable();

    // save context so the singleton pattern is respected
    this.requestService = this.requestService.bind(this);
  }

  public requestService(arg: ServiceArgs) {
    this.serviceRequested.next(arg);
  }
}

বিকল্পভাবে, আপনি ক্লাসের সদস্যদের public staticপরিবর্তে কেবল ঘোষণা করতে পারেন public, তারপরে প্রসঙ্গটি কোনও বিষয় নয়, তবে আপনাকে SubscriptableService.onServiceRequested$নির্ভরতা ইনজেকশন ব্যবহার করার পরিবর্তে এবং তাদের মাধ্যমে অ্যাক্সেস করার পরিবর্তে এগুলি অ্যাক্সেস করতে হবে this.subscriptableService.onServiceRequested$


0

পিতামাতা এবং শিশুদের পরিষেবা

পিতা-মাতার পরিষেবা এবং এর শিশুটিকে বিভিন্ন দৃষ্টান্ত ব্যবহার করে আমার সমস্যা হয়েছে। একটি উদাহরণ ব্যবহার করতে বাধ্য করার জন্য, আপনি আপনার অ্যাপ্লিকেশন মডিউল সরবরাহকারীগুলিতে সন্তানের সাথে রেফারেন্স সহ পিতামাতাকে উপন্যাস করতে পারেন। পিতামাতারা সন্তানের বৈশিষ্ট্যগুলিতে অ্যাক্সেস করতে পারবেন না, তবে একই উদাহরণ উভয় পরিষেবার জন্য ব্যবহৃত হবে। https://angular.io/guide/dependency-injection-providers#aliased-class-providers

app.module.ts

providers: [
  ChildService,
  // Alias ParentService w/ reference to ChildService
  { provide: ParentService, useExisting: ChildService}
]

আপনার অ্যাপ্লিকেশন মডিউলগুলির সুযোগের বাইরে উপাদানগুলির দ্বারা ব্যবহৃত পরিষেবাগুলি

কোনও উপাদান এবং পরিষেবা নিয়ে একটি গ্রন্থাগার তৈরি করার সময়, আমি একটি ইস্যুতে দৌড়েছি যেখানে দুটি দৃষ্টান্ত তৈরি করা হবে। একটি আমার কৌণিক প্রকল্প দ্বারা এবং একটি আমার গ্রন্থাগারের অভ্যন্তরের উপাদান দ্বারা। ঠিক করা:

আমার-outside.component.ts

@Component({...})
export class MyOutsideComponent {
  @Input() serviceInstance: MyOutsideService;
  ...
}

আমার-inside.component.ts

  constructor(public myService: MyOutsideService) { }

আমার-inside.component.hmtl

<app-my-outside [serviceInstance]="myService"></app-my-outside>

আপনার নিজের প্রশ্নের উত্তর দেওয়ার অর্থ কি? যদি তা হয়, তবে প্রশ্নটি পোস্ট হওয়ার পরে আপনি উত্তরটি স্ট্যাকওভারফ্লোতে একটি আনুষ্ঠানিক উত্তরে আলাদা করে আলাদা করে রাখতে পারেন, পোস্ট পোস্ট করার পরে উত্তর ক্ষেত্রে এটি কেটে / পেস্ট করে।
ryanwebjackson
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.